一.什么是同源
所谓同源就是协议、域名、端口三者完全一样,同源策略是浏览器上为安全性设置的重要机制,Ajax可以获取同源的数据,而对于非同源的数据,Ajax默认是获取不到的。
例如,有一个url地址为http://www.example.com:80,我们用表格简单区分一下同源与非同源
url | 结果 | 说明 |
---|---|---|
https://www.example.com | 非同源 | 协议不同,http与https |
http://en.example.com | 非同源 | 域名不同 |
http://www.example.com:81 | 非同源 | 端口号不同 |
http://www.example.com:80/index.html | 同源 | 协议、域名、端口号完全相同 |
如果使用Ajax请求了非同源路径下的数据,通常会报如下错误:
二.跨域
所谓跨域就是为了访问别人服务器的数据,Ajax是访问自己服务器的数据。
三.跨域的实现
XMLHttpRequest对象默认情况下是无法获取到非同源服务器下的数据。如果要获取其数据需要通过script标签,用script标签的src属性引入一个外部文件,这个外部文件是不涉及到同源策略影响。
<script type="text/javascript" src="http://www.wangle.run/test.js"></script>
跨域的本质其实就是服务器返回的一个方法调用,这个方法是我们事先定义好的,而方法中的参数就是我们想要的数据。
跨域请求大致分为四个步骤:
1.访问外部文件;2.动态创建script标签传入动态参数;3.前端界面决定方法名称;4.给window增加属性进行方法定义
四.跨域的封装
//跨域封装
function myDomain(obj){
var defaults = {
type:"get",
url:"#",
data:{},
success:function(data){},
jsonp:'',
jsonpCallback:'',
};
for(var key in obj){
defaults[key] = obj[key];
}
var params = "";
for(var attr in defaults.data){
params += attr + "=" + defaults.data[attr] + "&";
}
if(params){
params = params.substring(0,params.length-1);
defaults.url += "?" + params;
}
defaults.url += "&"+ defaults.jsonp + "=" + defaults.jsonpCallback;
var script = document.createElement("script");
script.src = defaults.url;
window[defaults.jsonpCallback] = function(data){
defaults.success(data);
}
var head = document.querySelector("head");
head.appendChild(script);
}
参数名 | 类型 | 说明 |
---|---|---|
type | String | 默认为get,跨域请求的方式通常都为get |
url | String | 服务器接口请求地址 |
data | Object | 请求的参数值,采用键值对形式。data:{ key: value } |
jsonp | String | 调用的方法key值,可自定义。如果服务器已指定则必须传入指定方法名 |
jsonpCallback | String | 调用方法名,可自定义 |
实例代码:
myDomain({
type:"get",
url:"https://www.example.com",
data:{
key:value,
},
jsonp:"callback",
jsonpCallback:"text",
success:function(data){
console.log(data)
}
})