Javascript 将字符串附加到服务工作者内的用户代理
我已经在这个问题上纠缠了一段时间了。我已经做了深入的研究,花了很多时间研究类似的问题,但都没有成功 一点背景知识。我有一个网站和一个android应用程序,可以有效地以不同的形式呈现网站,并显示不同的内容等等。。。应用程序知道如何从传入的请求中执行此操作,因为用户在用户代理中附加了一个特定的字符串(假设该字符串为“MobileAppRequest”)。在用户代理中检测到此字符串时,服务器知道返回不同的html文件。这允许用户仍然在浏览器上访问网站,使用web版本,并从android应用程序获得应用程序体验 现在,在使用服务工作者时,它默认为用户的标准用户代理,而不包括应用程序中附加的字符串。然后返回应用程序中的web版本,这会把事情搞砸。我需要知道如何设置自定义头,或者实际上如何在服务工作者中向用户代理附加字符串。它说,当我试图直接更改它时,头是不可变的,但我知道一种解决方法是提出一个新的请求作为响应 这是我的SW.jsJavascript 将字符串附加到服务工作者内的用户代理,javascript,browser-cache,service-worker,Javascript,Browser Cache,Service Worker,我已经在这个问题上纠缠了一段时间了。我已经做了深入的研究,花了很多时间研究类似的问题,但都没有成功 一点背景知识。我有一个网站和一个android应用程序,可以有效地以不同的形式呈现网站,并显示不同的内容等等。。。应用程序知道如何从传入的请求中执行此操作,因为用户在用户代理中附加了一个特定的字符串(假设该字符串为“MobileAppRequest”)。在用户代理中检测到此字符串时,服务器知道返回不同的html文件。这允许用户仍然在浏览器上访问网站,使用web版本,并从android应用程序获得应
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);
})
);
});