跨域是由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
存在跨域的情况:
1、网络协议不同,如http协议访问https协议。
2、端口不同,如80端口访问8080端口。
3、域名不同,如qianduanblog.com访问baidu.com。
4、子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com。
5、域名和域名对应ip,如www.a.com访问20.205.28.90.
如下图:
实现跨域的方法(前两种方法前端不常用):
(1)、porxy代理
定义和用法:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。
实现方法:通过nginx代理;
注意点:1、如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。
(2)、CORS 【Cross-Origin Resource Sharing】
定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下
res.writeHead(200, {
"Content-Type":
"text/html; charset=UTF-8",
"Access-Control-Allow-Origin":'http://localhost',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers':
'X-Requested-With, Content-Type'
});
(3)、jsonp
定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。
特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。
实例如下:(实际项目中JSONP通常用来获取json格式数据,这时前后端通常约定一个参数callback,该参数的值,就是处理返回数据的函数名称。)
html:
//原生js
<html>
<head>
<title></title>
第一种方式:
<script type="text/javascript">
var returnjs = function(data){
alert(data.code);
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "http://www.return.com/jsonp/get?code=1&callback=returnjs";//数据接收后台
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
第二种方式:
<script>
var f = function(data){
alert(data.name);
}
var _script = document.createElement('script');
_script.type = "text/javascript";
_script.src = "http://localhost:8888/jsonp?callback=f";
document.head.appendChild(_script);
var query = _url.query;
console.log(query);
var params = qs.parse(query);
console.log(params);
var f = "";
f = params.callback;
res.writeHead(200, {"Content-Type": "text/javascript"});
res.write(f + "({name:'hello world'})");
res.end();
</script>
</head>
<body>
</body>
</html>
//jQ版
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here1</title>
<script type="text/javascript" src="jq.js"></script><!-- 记得引入jq -->
</head>
<body>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
// 注意:post不能提交。
// jsonp:
// response.setContentType( "text/javascript; charset=utf-8" );
// json:
// response.setContentType( "application/json; charset=utf-8" );
type: "get",
async: false,
url: "http://www.return.com/jsonp/get?code=1",//数据接收后台
dataType: "jsonp", // datatype can be json or jsonp
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"returnjs",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
crossDomain:true,
success: function(json){
alert(json.code);
},
error: function(){
alert('fail');
}
});
});
</script>
</body>
</html>
缺点:
1、这种方式无法发送post请求(点击这里看详情)
2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。