Ajax "GET" to intra-service >> CMS serviceworker answers OK when OFFLINE
下午好,
我们正在使用开源 CMS。我们升级的最后一个版本,它带有一个新功能,它是一个 javascript serviceworker 实现来处理所有的请求。
这个 CMS 有一些用户交互的工作流表单(由我们设计)。在设计时,你可以在它们上面添加一些自定义的 html 作为一个特殊的片段元素,它可以容纳你想要的所有 JS、HTML 和 CSS 代码。
我们创建了一个按钮,点击后将 $.get() 发送到我们在同一机器实例 (https://localhost:5000/) 上在线/活动的 Python Flask 服务器。
使用升级前的先前 CMS 版本(上面没有 serviceworker),如果我们停止了 Flask 服务器,在单击 $.get() 按钮时我们会收到预期的错误 (404/500),因此我们可以处理它带有 ".fail()" jQuery 部分。但是如果 Flask 处于活动状态,我们会在 ".done()" 部分处理它。
现在,一切都落在 ".done()" 上,因为即使它应该失败(因为 Flask 离线),serviceworker "middle-catches" 它并以 OK (200) 解决:
当实际服务器宕机时:
那么,知道我们不能以任何方式更改 serviceworker 代码,我们如何避免 serviceworker 捕获 ajax 调用?
我们能否以某种方式扩展它,在 "fetch" 侦听器上添加对 "/api" url 的验证,以仅 "return;"?
这是 Chrome 所说的重点:
和一段函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | self.addEventListener('fetch', function (event) { //https://stackoverflow.com/questions/48463483/what-causes-a-failed-to-execute-fetch-on-serviceworkerglobalscope-only-if if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { return; } var fetchRequest = event.request.clone(); event.respondWith( fetch(fetchRequest) .then(function (response) { //redirect links eg. /jw/home, userview root url, are of response.type 'opaqueredirect', and possibly response.status != 200 //it is generally not a good idea to cache redirection because the content (target of redirection) might be changed //https://medium.com/@boopathi/service-workers-gotchas-44bec65eab3f //but without this the top-right home button (/jw/home) will never be cached and will always show offline page when being accessed offline //if (!response || response.status !== 200 || response.type !== 'basic' || event.request.method !== 'GET') { if (!response || event.request.method !== 'GET') { return response; } else { if(fetchRequest.url.indexOf('/web/json/workflow/currentUsername') === -1 && fetchRequest.url.indexOf('/images/v3/cj.gif') === -1 && fetchRequest.url.indexOf('/images/favicon_uv.ico?m=testconnection') === -1){ var responseToCache = response.clone(); caches.open(cache) .then(function (cache) { cache.put(event.request, responseToCache); }); } } return response; }) .catch(function () { if(event.request.method === 'POST' && formData !== null){ console.log('form POST failed, saving to indexedDB'); savePostRequest(event.request.clone().url, formUserviewAppId, formPageTitle, formData, formUsername); //redirect instead var response = Response.redirect(self.registration.scope + '/_/pwaoffline', 302); return response; }else{ if(fetchRequest.url.indexOf('/images/favicon_uv.ico?m=testconnection') > -1){ //var response = new Response(new Blob(), {"status" : 404 }); return null; } return new Promise(function(resolve, reject) { caches.match(event.request).then(function(response){ if(response === undefined){ var offlineResponse = Response.redirect(self.registration.scope + '/_/offline', 302); resolve(offlineResponse); }else{ resolve(response); } }) }); } }) ); |
});
非常感谢和问候。
好吧,没有答案。好的。
所以如果有人感兴趣,我会解释我是如何解决它的。
基本上,用一个 "rodeo":
- 无法更改 serviceworker 功能(因为它是第 3 方软件,我无法编辑)。
- 所以唯一的方法是每次都"避免缓存",每次 ajax 调用都使用"缓存:假"。
- 这样 SW 无法提供"离线"版本的页面,即使在线,我也不会每次都收到真实页面(缓存,但真实)。
- 因此,在回忆 .done() 和 .fail() 时,一切都变为 "done()"(因为一切正常),但我检查了那里的响应内容,就像过去一样......这如果服务器在线,它会以正确的预期响应解析真正的 200 OK。但是如果它是离线的,因为我使用了 "cache: false" 参数,即使使用 SW OK 200,响应也不会带有真正的预期响应文本。所以条件失败,我可以将其视为真正的 404。
简单,仅此而已。