为什么会出现跨域问题
跨域是指从一个域名的网页去请求另一个域名的资源。浏览器出于安全的考虑,不允许不同源
的请求;
因为浏览器收到同源策略
的限制,当前域名的js只能读取同域下的窗口属性。
同源策略是指:不同的域名, 不同端口, 不同的协议不允许共享资源,保障浏览器安全。
处理方法
jsonp 跨域方法
同源策略会阻止ajax请求;但不阻止具有src属性的标签,所以动态创建script
标签即可。具体如下:
我们提供一个 script
标签。请求页面中的数据, 同时传入一个回调函数的名字。服务器端得到名字后,
拼接函数执行格式的字符串。发送回浏览器。script 在下载代码以后并执行, 执行的就是这个函数调
用形式的字符串,
因此就将本地函数调用了.同时拿到了从服务器端得到的数据。
举个例子,假如需要从服务器(http://www.a.com/user?id=123)获取的数据如下:
{"id": 123, "name" : 张三, "age": 17}
那么,使用JSONP方式请求(http://www.a.com/user?id=123?callback=foo)的数据将会是如下:
foo({"id": 123, "name" : 张三, "age": 17});
当然,如果服务端考虑得更加充分,返回的数据可能如下:
try{foo({"id": 123, "name" : 张三, "age": 17});}catch(e){}
这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123?callback=foo
:
便可以使用foo函数来调用返回的数据了。
CORS 跨域
CORS 是在 es5 之后提出的跨域方案. 只需要在服务器配置一个跨域响应头接口
允许你的域名来获取我的数据
response[‘Access-Control-Allow-Origin’] = “*”
允许你携带Content-Type请求头
response[‘Access-Control-Allow-Headers’] = “Content-Type”
允许你发送DELETE,PUT
response[‘Access-Control-Allow-Methods’] = “DELETE,PUT”
CORS请求头的注意事项:
- 简单请求:
只要同时满足以下两大条件,就属于简单请求。
(1 ) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、
text/plain
- 复杂请求:
- 会发送两次请求- 首先会发送options请求做预检
- 然后再发送真正的 PUT/POST….请求
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP(options)查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
CORS与jsonp相比的优点:
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP
有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经
支持了CORS。