跨域资源请求CORS
1.什么是跨域资源请求
- 通常情况下,我们访问一个网站的过程如下:
- 访问页面example.com,加载页面html以及js
- 对页面进行一些操作,由js通过ajax访问后台,进行页面的更新.
- 一般情况下,通过ajax调用后台是同源的,同源指的是:
- 协议相同
- 端口号相同
- 地址相同
- 但是有时候通过js请求非同源的后台服务,这个时候就是属于跨域资源请求了
2.问题
- 由于Ajax的同源设置策略,所以如果我们直接请求非同源的地址的话,会出现错误
3.解决方法
1. 作为用户
- 安装chrome插件Allow-Control-Allow-Origin后启用即可.
2.作为开发者
- 当浏览器发现ajax请求是跨域请求时,会在请求头上面添加origin字段,这个字段将作为服务器指定是否允许同源请求的地址
- 在服务器上,我们需要配置web.xml中SpringServlet的初始化参数,如下
- 其中,CrosbyFilter代码如下:
- 需要注意的是头部添加的三个值:
- Access-Control-Allow-Origin:其值为允许跨域访问的源地址,可以为*匹配所有或者具体的源地址
- Access-Control-Allow-Headers:CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定,如上面代码所示,在返回里面添加了msgversion的头部信息,如果不需要额外信息此项可不写
- Access-Control-Allow-Credentials:表示是否允许发送Cookie,这个值也只能设为true,如果服务器不要浏览器发送Cookie,不要添加该字段即可
- 修改之后,跨域访问时可以看到返回的内容为:
3.总结
- 总的来说,简单跨域请求主要的操作是还是在服务器端进行操作,大部分浏览器都能够自动地进行跨域的访问,上面所提到的也仅仅是简单的跨域资源请求,更多的资料可以去查看http://www.ruanyifeng.com/blog/2016/04/cors.html
jQuery中ajax请求的跨域问题
最近用到了百度地图的web api,想要通过ajax get来获得内容,没想到都跨域了.解决方法如下(其中success的值为自定义的回调函数)
var options = {
type: "get",
dataType:"jsonp",
jsonp:"callback",
url: serviceURL,
//dataType: 'json',
timeout: timeout || 20000,//超时时间设置,单位毫秒
success: callBack
};
$.ajax(options);
原理JSONP
参考http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html中JSONP部分内容
局限
jsonp只能是解决get方法的跨域问题,如果是post的话,还是需要修改服务器的相关内容(参照上面解决方法中开发者的部分)