PWA开发中遇到的坑:缓存策略会导致 URL 参数的问题,和中文可能乱码的问题(一)

技术文摘1年前 (2023)更新 8kmm.com
10K 0 1

小编在开发www.8kmm.com导航的PWA(Progressive Web Apps,渐进式 Web 应用)时遇到问题。

问题一: 在跳转时,遇到URL参数带中文后乱码;

问题二:在使用了PWA后, url带参数就会影响service works缓存问题。

特记录一下:

先解决问题二,顺便把问题一也解决了。

本站做为默认搜索引擎时,

https://s.8kmm.com?wd=测试

会301跳转到:

https://www.8kmm.com/bookmark/?wd=测试

这个时候,当主站www.8kmm.com启用了pwa时, 搜索跳过来就会报: 会提示:https://www.8kmm.com/bookmark/?wd=测试  的网页可能暂时无法连接,或者它已永久性地移动到了新网址。 ERR_FAILED,

注销掉“开发者工具”=》Serivce works中的工作进程就又可以。

思来想去, 应该是URL带了参数,会导致sw缓存出问题, 第一次访问是正常的, 第二次用同样的参数过来,就会报这个错,本质上问题是重定向到了新 URL,而缓存策略并没有正确地处理这种情况。在这种情况下,在fetch事件中判断响应是否为重定向,并相应地进行处理,应该就能解决问题。

我们只需要判断在需要接收url参数的页面,进行单独处理:

self.addEventListener('fetch', event => {
  const request = event.request;

  // 检查请求是否为 bookmark 页面
  if (request.url.includes('/bookmark/')) {
    const url = new URL(request.url);

    // 检查 URL 是否包含查询参数
    if (url.search) {
      // 编码查询参数后再进行 fetch
      const encodedUrl = url.origin + url.pathname + encodeURI(url.search);
      return event.respondWith(fetchWithRedirects(encodedUrl));
    }
  }

  // 其他处理逻辑不变
  ...
});

async function fetchWithRedirects(requestUrl) {
  let response;
  let redirects = [];

  do {
    response = await fetch(requestUrl, { redirect: 'manual' });

    if (response.status === 301 || response.status === 302) {
      // 获取重定向目标 URL 并记录
      const redirectUrl = new URL(response.headers.get('location'), requestUrl);
      redirects.push(redirectUrl.href);

      // 更新 requestUrl
      requestUrl = redirectUrl.href;
    }
  } while (response.status === 301 || response.status === 302);

  // 响应是否为重定向,如果是则应用重定向
  if (redirects.length > 0) {
    caches.open(currentCache).then(cache => {
      cache.put(requestUrl, response.clone());
    });
    return Response.redirect(redirects[redirects.length - 1], 302);
  }

  // 响应不是重定向,则正常处理
  const cache = await caches.open(currentCache);
  cache.put(requestUrl, response.clone());
  return response;
}

这段代码检查了响应状态是否为 301 或 302,如果是则获取重定向目标 URL 并记录。然后更新requestUrl,并循环进行fetch,直到响应不再是重定向。最后,如果响应是重定向,会返回一个Response.redirect(),并将响应存储在缓存中。

注意:const encodedUrl = url.origin + url.pathname + encodeURI(url.search);  中的encodeURI将中文编码,用于解决中文乱码的问题。

 

另外, 在使用PHP做301跳转时,如果出现中文乱码问题,可以使用

header(‘HTTP/1.1 301 Moved Permanently’);
header(‘Location: ‘ . $myurl);
header(‘Content-Type: text/html; charset=UTF-8’);

示例代码:

$myurl='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
if (isset($_GET['wd']) && $_GET['wd'] !== '') {
    if (strpos($myurl, '?') === false) {
        $myurl .= '?wd=' . urlencode($_GET['wd']);
    } else {
        $myurl .= '&wd=' . urlencode($_GET['wd']);
    }
}
if (isset($_GET['t']) && $_GET['t'] !== '') {
    if (strpos($myurl, '?') === false) {
        $myurl .= '?t=' . urlencode($_GET['t']);
    } else {
        $myurl .= '&t=' . urlencode($_GET['t']);
    }
}
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $myurl);
header('Content-Type: text/html; charset=UTF-8'); //可在此处进行指定字符集操作。
exit;
© 版权声明

相关文章

文章目录

    暂无评论

    暂无评论...