什么是跨域?
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
通常我们所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景
什么是同源策略?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同
常见跨域场景
跨域场景解决方案
1、 通过jsonp跨域
2、 跨域资源共享(CORS)
3、 nginx代理跨域
一:通过jsonp跨域
/***
* 就是利用<script>标签没有跨域限制的“漏洞”来达到与第三方通讯的目的。
* 当需要通讯时,本站脚本创建一个<script>元素,地址指向第三方的API网址,
* 形如:<script src="http://www.baidu.com/api?param1=1¶m2=2"></script>
* 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)
* 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),
* 形如:handleCallback({"name":"hax","gender":"Male"}) 这样浏览器会调用callback函数,
* 并传递解析后 json对象作为参数
***/
//原生写法
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.baidu.com:8080/api?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
//jquery写法
$.ajax({
url: 'http://www.baidu.com:8080/api',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {}
});
jsonp缺点:只能实现get一种请求。
二:跨域资源共享(CORS)
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10
(IE8/9需要使用XDomainRequest对象来支持CORS)
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)
这里只介绍简单请求,非简单请求可点击这里
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信
// 1:服务端不需要cookie信息的情况
前端:什么都不用做
后端:Access-Control-Allow-Origin : //必须 http://domain.com 或 * 号
Access-Control-Allow-Credentials //可选
Access-Control-Expose-Headers //可选
// 2:服务端需要cookie信息的情况
前端:在AJAX请求中打开withCredentials = true
后端: Access-Control-Allow-Origin : //必须 http://domain.com,且不能为 * 号
Access-Control-Allow-Credentials: //必须 true
Access-Control-Expose-Headers: //可选
三:nginx代理跨域
server {
listen 80;
server_name m.youmias.com;
location / {
proxy_pass http://123.57.216.192:8080; //个人公网ip
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://123.57.216.192:8080; //个人公网ip
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
网友评论