同源和跨域
如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源。
非同源即收到跨域限制:浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互,例如:
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
- 无法接触非同源网页的 DOM
- 无法向非同源地址发送 AJAX 请求
常见的解决跨域的方法有:CORS、JSONP、NGINX反向代理等。
CORS
CORS浏览器端是全自动的,不需要开发者参与,主要看服务端对CORS的设置。
为了防止请求成功发起导致数据库数据受到影响,规定对简单请求以外的请求方式在发起前先使用OPTIONS
方法发起一个预检请求(Preflight)判断是否支持CORS,如果不允许则不发送真实请求。
简单请求
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。
同时满足下述两个条件则为“简单请求”:
- 请求header里只能有以下字段
- accept
- accept-language
- content-language
- content-type
- 请求方式为以下三种之一
- GET
- HEAD
- POST(仅当Content-Type值等于下列之一才算简单请求,用于兼容form表单,因表单一直可以支持跨域请求)
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
非简单请求
通常即PUT、PATCH、DELETE、POST(Content-Type字段的类型是application/json)。
对于非简单请求会先用OPTIONS方法预检。
JSONP
JSONP是JSON with Padding的略称。它是一个 非官方 的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
JSONP只支持GET请求,但兼容性更好,支持老式浏览器,以及可以向不支持CORS的网站请求数据。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
<script>
标签的src
属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。JSONP前端创建一个回调函数,然后在远程服务上利用
<script src=''></script>
调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。采用jquery的
$.ajax
时,dataType:'jsonp'
即可
$.ajax({
type: "get",
url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(需要和服务器端约定,一般默认为:callback)
jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,jQuery会自动为你处理数据
success: function(json){
//如不写jsonpCallback,则可以在此处进行回调
},
error: function(){
}
});