Skip to content

PWA实践经验 -- fetch #25

@p2227

Description

@p2227

sw中fetch使用注意要点

透明请求

sw在建立的时候,有一种叫做prefetch的行为,就是当你第一次install及每次update sw的时候,sw都会把一个列表里面的所有资源请求一次,然后缓存起来。这个请求是由fetch发起的。

我们在html里面如果想要请求某个js,直接script标签引用就可以了,根本不需要考虑这个资源是在哪个域下的。但如果在sw里面,因为fetch本质还是由js发起的,所以要遵循同源策略。

于是我在实践PWA的过程中,就遇到一个问题,缓存的资源都是cdn上的,cdn域与页面的域不一样。

对于跨域问题,其实目前最通用的做法是CORS,即由服务器返回特定的http响应头,浏览器解释到有这个响应头,就不报错。详细可见: http://www.ruanyifeng.com/blog/2016/04/cors.html

针对sw而言,因为有sw就必须是https的页面,https是不允许Access-Control-Allow-Origin: *的,但是同时有跨域请求的域不止一个,这就要求服务器要动态根据请求的域,判断是否合法,再动态加入 Access-Control-Allow-Origin 响应头。而且还是要加在cdn上,这对后端的要求就有点高了,有没有纯前端能解决的方法呢?

有的,针对sw这种特殊应用场景,fetch中的request对象有这样一个参数
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode 当mode为no-cors时,这个请求叫透明请求( opaque request),它的意义是这样的:浏览器正常请求,忽略CORS头,请求的响应可以存到cache里面,但是js不能访问请求的细节。详细可参考stackoverflow。所以我们把请求设置成 {mode: "no-cors"}就可以不用动态设置CORS但是能缓存相应的资源了。

cookies

前面 #24 的时候,我有说过,我测试环境和生产环境的域是一样的,那么我们是怎么区分的呢?用cookies,当然这会有一个困扰的问题,就是在联调的时候老是会访问到了线上的资源,资源名字有hash,会导致404,当然在开发的时候可以手动停掉sw去避免这问题,但毕竟不是好方法。我在查阅上面透明请求的资料时,也查到了这一方面的配置,就是 https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials ,fetch请求带上 include配置顶,会把cookie带上,于是就能顺利地进行各种开发调试和生产访问了。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions