跨域问题及解决方案

先简单说下什么是跨域?
跨域是指一个域下的文档或者脚本视图请求另外一个域下的资源。
如:
A链接、重定向、表单提交
js发起的ajax请求
特别需要注意的是:
不同端口或者 主域名相同子域名不同的 都是属于跨域。
这也就是 浏览器的同源策略,这个约定要求请求资源是需要 协议+域名+端口 三者相同才行.
不然会出现错误提示

 XMLHttpRequest cannot load http://xxxxxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

解决方法

  • 使用jsonp跨域
  • 使用跨域资源共享(cors)
  • 使用nginx代理跨域

使用jsonp跨域

jsonp的原理实际上是创建一个script标签,然后赋值src,赋值时浏览器会发起一个请求.服务器响应后,通过jsonpCallback回调方法接受响应的数据.
例子:

$.ajax({
	url: 'http://abc.com',
	type: 'get',
	dataType: 'jsonp',
	jsonpCallback: 'handleCallback',
	data:{}
})

原生实现:

<script>
var st = document.createElement('script');
    st.type = 'text/javascript';
    st.src = 'http://www.aaa.com/login?callback=handleCallback';
    document.head.appendChild(st);

    // 回调执行函数
    function handleCallback(res) {
        doit....;
    }
</script>

使用跨域资源共享(cors)

普通跨域的话,在后端的响应体中这是Access-Control-Allow-Origin 为 ”*“即可。
若要带cookie的请求,前后端都需要设置
后端处理(python)

	resp = make_response(resp)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'
    resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
    return resp

前端jq:

$.ajax({
	url: 'http://abc.com',
	type: 'get',
	dataType: 'jsonp',
	jsonpCallback: 'handleCallback',
	data:{},
	xhrFields:{
		withCredentials:true
	},
	crossDomain:true
})

使用nginx代理跨域

实现原理 通过nginx配置一个代理服务器,反向代理访问目标接口,并修改cookie中的domain信息完成跨域

server{
	listen 8080;
	server_name www.aaa.com;
	location / {
	proxy_pass http://www.bbb.com;#反向代理
	proxy_cookie_domain www.bbb.com www.aaa.com#修改cookie的domain
	index index.html;
	add_header Access-Control-Allow-Origin http://www.aaa.com;
	add_header  Access-Control-Allow-Credentials true;
	}
}

常用就上面的3种,当然还有
修改document.domain+iframe跨域
用nodejs做中间件代理跨域

这两种也是基于修改请求源进行更改。 使用代理做跳板修改 Access-Control-Allow-Origin

使用websocket协议跨域
这个比较新,原理上是使用了底层的socket-io请求进行访问,建立新的链接进行请求资源。

你可能感兴趣的:(前端)