将字符串附加到Service Worker中的用户代理

时间:2018-11-14 12:06:09

标签: javascript browser-cache service-worker

我已经在这个问题上停留了一段时间。我已经进行了深入研究,并花了很多时间在SO上寻找类似的问题-但未成功。

有点背景。我有一个网站和一个android应用程序,可以有效地以不同的形式显示不同的网站,并具有不同的显示效果等。该应用程序知道可以通过传入请求来执行此操作-因为用户在用户代理上附加了特定的字符串(我们只是说字符串为“ MobileAppRequest”)。在用户代理中检测到此字符串后,服务器便知道要返回不同的html文件。这样一来,用户仍然可以在其浏览器上访问该网站并使用网络版本,并且可以从其Android应用程序中获得应用程序体验。

现在,在使用服务工作者时,它默认为用户的标准用户代理,而不包含应用程序中附加的字符串。然后,它返回应用程序内的网络版本,将其全部弄乱了。我需要知道如何设置自定义标头,或者实际上是将字符串附加到服务工作者中的用户代理。它说,当我尝试直接更改标头时,标头是不变的,但我知道解决此问题的方法是发出新请求作为响应。

这是我的SW.js

var CACHE_STATIC_NAME = 'static-v10';
var CACHE_DYNAMIC_NAME = 'dynamic-v2';

self.addEventListener('install', function (event) {
  console.log('[Service Worker] Installing Service Worker ...', event);
  event.waitUntil(
    caches.open(CACHE_STATIC_NAME)
      .then(function (cache) {
        console.log('[Service Worker] Precaching App Shell');
        cache.addAll([
          '/',
          '/static/media/next.png',
          '/static/media/previous.png'
        ]);
      })
  )
});

self.addEventListener('activate', function (event) {
  console.log('[Service Worker] Activating Service Worker ....', event);
  event.waitUntil(
    caches.keys()
      .then(function (keyList) {
        return Promise.all(keyList.map(function (key) {
          if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
            console.log('[Service Worker] Removing old cache.', key);
            return caches.delete(key);
          }
        }));
      })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetch(event.request)
      .then(function(res) {
        return caches.open(CACHE_DYNAMIC_NAME)
                .then(function(cache) {
                  cache.put(event.request.url, res.clone());
                  return res;
                })
      })
      .catch(function(err) {
        return caches.match(event.request);
      })
  );
});

我希望答案包含完整的sw.js或您正在编辑的整个函数,以确保在集成到代码中时不会出现任何错误。

2 个答案:

答案 0 :(得分:2)

正如我在评论中提到的那样,如果您使用 let dismissKeyboard = UITapGestureRecognizer(target: self, action: #selector(CreateRoomsViewController.dismissKeyboard(_):))) dismissKeyboard.numberOfTapsRequired = 1 view.addGestureRecognizer(dismissKeyboard) // Do any additional setup after loading the view. } func dismissKeyboard(tap: UITapGestureRecognizer) { view.endEditing(true) } ,则可以将所需的任何数据传递给Service Worker。

下面是使用脚本的示例。

webpage.html

postMessage()

SW.js

<script>
  // creates ServiceWorker
  var worker = new Worker('SW.js');
  // sends the browser's userAgent to the ServiceWorker
  worker.postMessage(window.navigator.userAgent);
</script>

虽然浏览SO非常适合作为示例,但是有时候,如果您的选择有限,最好参考文档。

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

答案 1 :(得分:0)

我已经编辑了您的代码以在获取请求中添加自定义标头。您应该尝试一下,它将起作用。

对于您的用例,您只想为域请求添加自定义标头,因此我添加了一个正则表达式检查,该检查将检查并添加自定义标头以仅提取与您的域有关的请求。 (为本地测试添加了本地主机)。对于与其他域有关的提取请求,它将发送标准标头。

您需要传递一些其他参数来提取调用,这是我添加的。 在您的应用程序中,根据需要编辑“ CUSTOMHEADER”,“ CUSTOMVALUE”和YOURDOMAIN.com。

https://developer.mozilla.org/en-US/docs/Web/API/Headers上了解有关Header()的更多信息。 如果要修改useragent,请在答案的fetch事件中添加以下行,

var CACHE_STATIC_NAME = 'static-v10';
var CACHE_DYNAMIC_NAME = 'dynamic-v2';

self.addEventListener('install', function (event) {
  console.log('[Service Worker] Installing Service Worker ...', event);
  event.waitUntil(
    caches.open(CACHE_STATIC_NAME)
      .then(function (cache) {
        console.log('[Service Worker] Precaching App Shell');
        cache.addAll([
          '/',
          '/static/media/next.png',
          '/static/media/previous.png'
        ]);
      })
  )
});

self.addEventListener('activate', function (event) {
  console.log('[Service Worker] Activating Service Worker ....', event);
  event.waitUntil(
    caches.keys()
      .then(function (keyList) {
        return Promise.all(keyList.map(function (key) {
          if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
            console.log('[Service Worker] Removing old cache.', key);
            return caches.delete(key);
          }
        }));
      })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(event) {
    if(/^.*\:\/\/(?:localhost|YOURDOMAIN\.com)\/.*/.test(event.request.url))
    { var myHeader = new Headers(event.request.headers);
      myHeader.append('CUSTOMHEADER', 'CUSTOMVALUE');
      console.log('Custom Fetch Call:'+event.request.url);
      event.respondWith(
        fetch(event.request.url, {credentials: 'same-origin', redirect: 'follow', headers: myHeader}).then(function(res) {
            return caches.open(CACHE_DYNAMIC_NAME)
                    .then(function(cache) {
                      cache.put(event.request.url, res.clone());
                      return res;
                    })
          })
          .catch(function(err) {
            return caches.match(event.request);
          })
      );
      return
    }
    event.respondWith(
      fetch(event.request).then(function(res) {
        return caches.open(CACHE_DYNAMIC_NAME)
                .then(function(cache) {
                  cache.put(event.request.url, res.clone());
                  return res;
                })
      })
      .catch(function(err) {
        return caches.match(event.request);
      })
    );  


});

请注意:到目前为止,我们不建议更改“ User-Agent”,因为最近它已从禁止标题的列表中删除。因此,浏览器支持受到限制。

echo $_SERVER['HTTP_CUSTOMHEADER'];

您可以在服务CUSTOMVALUE上对其进行检查,它将回显$INSIDEAPP = (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'],'CUSTOMUSERAGENT') !== false))? true:false; $INSIDE_SW = (isset($_SERVER['HTTP_CUSTOMHEADER']))?true:false; $SERVE_APP_PAGE = $INSIDEAPP || $INSIDE_SW; if($SERVE_APP_PAGE) { //serve request of app page. } else { // serve normal request through browser } 。我已经通过服务器端和chrome网络面板对它的工作进行了交叉验证。

为了向您的android用户提供自定义应用页面,您应该使用(IN PHP):

tipcalculation