博客
说说跨域那些事儿
不要再问我跨域的问题了
前端常见跨域解决方案(全)
同源策略
JSONP(填充式JSON)
JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。
其原理就是在客户端借助 script 标签请求服务端的一个动态网页(php 文件),服务端的这个动态网页返回一段带有函数调用的 JavaScript 全局函数调用的脚本,将原本需要返回给客户端的数据传递进去。
以后绝大多数情况都是采用 JSONP 的手段完成不同源地址之间的跨域请求
客户端 http://www.zce.me/users-list.html<script src="http://api.zce.me/users.php?callback=foo"></script>
服务端 http://api.zce.me/users.php?callback=foo 返回的结果
foo(['我', '是', '你', '原', '本', '需', '要', '的', '数', '据'])
总结一下:由于 XMLHttpRequest 无法发送不同源地址之间的跨域请求,所以我们必须要另寻他法,script 这种方案就是我们最终选择的方式,我们把这种方式称之为 JSONP,如果你不了解原理,先记住怎么用,多用一段时间再来看原理。
问题:
- JSONP 需要服务端配合,服务端按照客户端的要求返回一段 JavaScript 调用客户端的函数
- 只能发送 GET 请求
注意:JSONP 用的是 script 标签,更AJAX 提供的 XMLHttpRequest 没有任何关系!!!
jQuery 中使用 JSONP 就是将 dataType 设置为 jsonp
其他常见的 AJAX 封装 库:
Axios
1 获取到输入的值
2动态添加script标签(用来跨域传递参数) 注意将script添加进DOM树里
3给window添加属性方法(定义好后台会返回的调用方法)
<script type="text/javascript">
window.onload = function () {
document.querySelector('.btn').onclick = function () {
var city = document.querySelector('#input').value;
var script = document.createElement('script');
script.src = 'http://www.lisi.com/data.php?city='+city+'&callback=f1' ;
var head = document.querySelector("head");
head.appendChild(script);
window.f1=function (data) {
console.log(data);
}
}
};
</script>
CORS
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
// 允许远端访问
header('Access‐Control‐Allow‐Origin: *');
这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个 Access-
Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。
AJAX调用第三方接口的时候,也是跨域。但是接口提供方做了处理。
处理方式是CORS
跨域封装
function Ajax (object) {
var defaults = {
url: '#',
type:"get",
success:function (data) {},
data : {},
jsonp:"callback",
jsonpCallback:"hehe" //不是必须的
}
for(var key in object){
defaults[key] = object[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.jsonp+"="+defaults.jsonpCallback
}
var script = document.createElement('script')
script.src = defaults.url
console.log(defaults.url);
window[defaults.jsonpCallback]= function (data) {
defaults.success(data)
}
var head = document.querySelector("head");
head.appendChild(script);
}