PWA 实践经验 fetch
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 带上,于是就能顺利地进行各种开发调试和生产访问了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论