解决跨域问题

为什么会出现跨域问题

跨域是指从一个域名的网页去请求另一个域名的资源。浏览器出于安全的考虑,不允许不同源
的请求;
因为浏览器收到同源策略的限制,当前域名的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。

-------------The End-------------