Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将字符串附加到服务工作者内的用户代理_Javascript_Browser Cache_Service Worker - Fatal编程技术网

Javascript 将字符串附加到服务工作者内的用户代理

Javascript 将字符串附加到服务工作者内的用户代理,javascript,browser-cache,service-worker,Javascript,Browser Cache,Service Worker,我已经在这个问题上纠缠了一段时间了。我已经做了深入的研究,花了很多时间研究类似的问题,但都没有成功 一点背景知识。我有一个网站和一个android应用程序,可以有效地以不同的形式呈现网站,并显示不同的内容等等。。。应用程序知道如何从传入的请求中执行此操作,因为用户在用户代理中附加了一个特定的字符串(假设该字符串为“MobileAppRequest”)。在用户代理中检测到此字符串时,服务器知道返回不同的html文件。这允许用户仍然在浏览器上访问网站,使用web版本,并从android应用程序获得应

我已经在这个问题上纠缠了一段时间了。我已经做了深入的研究,花了很多时间研究类似的问题,但都没有成功

一点背景知识。我有一个网站和一个android应用程序,可以有效地以不同的形式呈现网站,并显示不同的内容等等。。。应用程序知道如何从传入的请求中执行此操作,因为用户在用户代理中附加了一个特定的字符串(假设该字符串为“MobileAppRequest”)。在用户代理中检测到此字符串时,服务器知道返回不同的html文件。这允许用户仍然在浏览器上访问网站,使用web版本,并从android应用程序获得应用程序体验

现在,在使用服务工作者时,它默认为用户的标准用户代理,而不包括应用程序中附加的字符串。然后返回应用程序中的web版本,这会把事情搞砸。我需要知道如何设置自定义头,或者实际上如何在服务工作者中向用户代理附加字符串。它说,当我试图直接更改它时,头是不可变的,但我知道一种解决方法是提出一个新的请求作为响应

这是我的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或您正在编辑的整个函数,我将不胜感激,这样我就不会在重新集成到代码中时出错。

我已经编辑了您的代码,以便在获取请求中添加自定义标题。你应该试试,它会有用的

对于您的用例,您只想为您的域请求添加自定义头,因此我添加了一个regex检查,它将检查并添加自定义头,以仅获取与您的域相关的请求。(为本地测试添加了localhost)。对于与其他域相关的获取请求,它将发送标准头

您需要传递一些额外的参数来获取调用,我已经添加了这些参数。 在应用程序中,根据需要编辑“CUSTOMHEADER”、“CUSTOMVALUE”和YOURDOMAIN.com

阅读有关Header()的更多信息,请访问。 如果要修改useragent,请在答案的fetch事件中添加以下行

  var myHeader = new Headers(event.request.headers);
  myHeader.delete('User-Agent');
  myHeader.set('User-Agent', 'CUSTOM_USERAGENTVALUE');
请注意:目前不建议更改“用户代理”,因为最近它已从禁止标题列表中删除。因此浏览器支持是有限的

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);
      })
    );  


});
您可以在服务
echo$_服务器['HTTP_CUSTOMHEADER']上查看它,它将回显
自定义值
。我已经通过服务器端和chrome网络面板交叉验证了它的工作

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


正如我在评论中提到的,如果您使用
postMessage()
,您可以将所需的任何数据传递给服务人员

下面是一个使用脚本的示例

webpage.html

虽然浏览SO是一个很好的例子,但有时当您有有限的选项时,最好参考文档


如果用户的浏览器注册了服务人员,为什么不在创建服务人员时传递浏览器的用户代理?那么您就不必处理软件用户代理。您所说的“通过”浏览器的用户代理是什么意思?如何实现这一点?使用
postMessage()
,是一种方法。它对您有用吗?不适合我。Cors错误,即使我将模式更改为无Cors。它表示:“”的FetchEvent导致了网络错误响应:“不透明”响应用于类型不是no cors的请求。另外,没有添加自定义标题(在注册软件后,我在加载主页时使用用户代理的控制台日志进行检查)。我编辑了代码并删除了模式:“cors”。我还检查了代码,它工作正常,并根据定义添加了自定义头。注意:您需要在初始加载后刷新页面一次,才能看到它工作。在初始页面加载时,服务工作者激活,在后续页面加载时,服务工作者截获请求并添加标题。我用此代码更新了它,但它仍然显示相同的标准UA。我在软件注册后刷新,但控制台日志仍显示相同的UA。你在chrome上测试过吗?在调整软件后,您是如何验证您的标题是否已更改的?我不建议您根据服务人员请求更改用户代理,因为它可能无法在某些旧浏览器中工作,因为它位于受限列表中,最近已被删除。你可以在fetch调用中添加自定义头,在服务器端,为包含自定义useragent(在android webview中设置)的请求以及具有自定义头的请求提供应用程序页面。我再次编辑了代码,并添加了一个fetch匹配模式和其他调整。我已经交叉验证了它在服务器端和chrome面板上都能正常工作。因为,在chrome面板上,有时不显示请求头。您现在应该尝试编辑代码。
$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
}
<script>
  // creates ServiceWorker
  var worker = new Worker('SW.js');
  // sends the browser's userAgent to the ServiceWorker
  worker.postMessage(window.navigator.userAgent);
</script>
var CACHE_STATIC_NAME = 'static-v10';
var CACHE_DYNAMIC_NAME = 'dynamic-v2';
// defines a global variable that will hold the UserAgent
var UA = '';

// listens to incoming postMessage()
self.addEventListener("message", function(event) {
  // update the UA variable with the event.data, which is the browser's UserAgent
  UA = event.data;
  console.log('ServiceWorker now has UA variable defined as ', UA);
}, false);

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) {
  // var myHeader = new Headers(event.request.headers);
  // myHeader.append('CUSTOMHEADER', 'CUSTOMVALUE');
  // you can now make a request using the passed UA
  event.respondWith(
    fetch(event.request, {credentials: 'same-origin', mode: 'cors', redirect: 'follow', userAgent: UA}).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);
      })
  );
});