又双叒叕是写在最前
所在的开发小组名叫”首页组”,但我觉得可以叫”块块组”。
一方面因为我们组的需求迭代速度真的是超级快,手头这个版本还没做完,下下版的prd就发来了。另一个原因是因为我们的最终任务就是呈现公司电视上的首页,而首页说粗暴点就是一个一个的块块,大块块套小块块。
但由于公司业务的越来越丰富,首页从原来最简单的呈现影视资源,到现在涉及到各大业务线。上面的大块块是影视,下面的大块块是教育,中间的大块块里的第n个小块块是商城,运营宝宝们想放什么放什么。
因此我们组的开发涉及到各业务线的对接,经常看到别家的产品跑去找我们家的产品,要求把他们的业务加到我们的下版需求里。有次听到我们的产品回应,你的这个需求只能排到以后了,我们下版需求早就排满了-0-
以上其实都是废话,但是我就是想写哈哈哈。
好啦好啦,重点就是我们怎么对接呢,跨域啊~
JSONP
原理
众所周知,浏览器存在同源策略机制,但Web页面上调用js文件时则不受是否跨域的影响。因此产生一种解决方案——web客户端通过调用脚本的方式,来调用跨域服务器上动态生成的js格式文件,服务器把客户端需要的数据装入进去。客户端调用成功后,只需要自己需求进行处理和展现了。
于是形成了一种JSONP这种传输协议,其要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
原生实现
|
|
ajax实现
实现方式
|
|
注意点
url
url后需要加上?callback=?
指定回调函数。
timeout
JSONP不支持超时设置,若遇到这种情况可以让后台进行处理。
async
JSONP不支持同步操作,因此设定async: false
无效。
多个JSONP
这是我初次开发时,纠结了很久的一个问题。当时使用JSONP,经常出现找不到对应回调函数的错误。网上很多错误说明都和callback传参有关,并不适用于我的情况。
先是发现我当时的同一页面调用了两个JSONP请求,而出错的总是后一个,因此考虑到应该是两个请求同时调用相关。当时想到的第一个方案是把设置async: false
,意图使用同步操作避免同时调用的问题。后来调试的时候发现请求依然是异步执行,查找了jQuery文档才发现不支持同步操作,因此有了上一个注意点。
之后发现我这两个请求用了同样的JSONPCallback
,尝试了区分成不同的变量,成功解决了这个问题。
后来瞄了下jQuery的这块的源码。
原来每次JSONP请求,都先在window上挂一个callbackName,返回后会移除callbackName。于是处理第一个返回时就把window[callbackName]
移除了,后续的返回都无法处理了。
源码大法万岁!!!
CORS(跨域资源共享)
两种请求
CORS请求分为简单请求和非简单请求两类。简单请求是指同时满足以下两个条件的请求——
- 请求方法是HEAD/GET/POST之一;
- HTTP的头信息不超出Accept/Accept-Language/Content-Language/Last-Event-ID/Content-Type(只限于application/x-www-form-urlencoded、multipart/form-data、text/plain这三个值)。
不同时满足的即为分简单请求。
实现
简单请求只需要服务端设置Access-Control-Allow-Origin
。
带cookie的请求,前后端都需要设置。
前端设置withCredentials为true。
后端设置Access-Control-Allow-Credentials
、Access-Control-Allow-Origin
以及cookie。
CORS vs JSONP
优缺点比较
- JSONP对浏览器的支持较好,IE10以下不支持CORS;
- JSONP只能用于获取资源(即只读,类似于GET请求);CORS支持所有类型的HTTP请求,功能完善。
- JSONP的错误处理机制并不完善,我们没办法进行错误处理;而CORS可以通过onerror事件监听错误,并且浏览器控制台会看到报错信息,利于排查。
- JSONP只会发一次请求;而对于复杂请求,CORS会发两次请求。