关于 javascript:Ajax \\”GET\\” to intra-service >> CMS serviceworker 在 OFFLINE 时回答 OK

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) 解决:

enter

enter

这是 Chrome 所说的重点:

enter

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。

简单,仅此而已。