小编在开发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;


