【Ajax】跨域的产生及如何解决跨域问题
什么是跨域? 为什么会出现跨域
浏览器为了保护用户, 保证用户安全,使用同源策略 来针对请求做出响应。
同源:
协议相同:protocol(ftp file http https 等协议)不同得协议被服务器认为不同源
域名相同:domain网站得域名必须一致。
端口相同:port默认80端口,但是不同端口也被认为跨域
以上任何不相同都被认为是跨域。
简单的说:
1 · 使用xmlHttpRequest,即我们通常说的ajax请求
2 · 浏览器做了这个事
3 · 访问的域名不同,即访问的html页面是a域名下的,但内部js发送的ajax请求的目标地址却是b域名
以上三个条件缺一不可,尤其是第三个条件,许多做移动端的同学可能都没有听过,因为移动端可以用各种http请求狂发不同的域名,但是浏览器不允许我们这么做
JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等。这是为了保证用户得安全。
说到底,跨域的原因是 前后端分离 ,跨域的目的是 安全
如何解决跨域问题(服务器代理, CORS,JSONP)
解决跨域问题的根本就是要打破上述的三个限制中的任何一个,我们可以逐个击破:
JSONP方式
jsonp是打破第一重限制,(因为)用了XMLHttpRequest就跨域,那不用这种方式了,我们来看一段jquery的带jsonp的ajax请求:
$.ajax({
type : "GET",
url : "http://api.map.baidu.com/geocoder/v2/",
data:"address=河南",
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"showLocation",
success : function(data){
alert("成功");
},
error : function(data){
alert("失败");
}
});
看似用了ajax请求,其实内部完全不是那么回事,多了jsonp和jsonpCallback选项,它内部将代码翻译并把页面上的dom操作成这样:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type='text/javascript'>
// 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,所以这里能拿到res。
window.showLocation = function (res) {
console.log(res)
//执行ajax回调
}
</script>
<script src='http://api.map.baidu.com/geocoder/v2/?address=河南&callback=showLocation' type='text/javascript'></script>
</body>
</html>
这个时候,html页面的script src标签回去访问api.map.baidu.com的服务端,由于script,img这种标签浏览器是不受xmlhttprequest限制的,可以随意访问,这个时候对应的后端代码取得address参数,最后根据双方约定好的callback参数,返回一个被包装后的json
上面我们为什么使用src标签(请求数据地址)?
script标签src允许跨域,我们利用script标签得src来访问资源,然后使用callback来承接返回得数据,并处理。
let input = document.queryselector("input")
input.oninput = function(){
let script = document.createElement("script")
let url = `https://s.search.bilibili.com/main/suggest?jsoncallback=mycallback&term=${input.value}`
script.src = url
document.body.appendChild(script)
script.onload = () => document.body.removeChild(script)
}
function mycallback(data){
console.log(data)
}
其中url是我们需要请求得src,在src中拼接了一个完整得get请求,包括请求得参数请求时发送的数据,以及回调接口。
将script添加到页面中的时候,script的代码会立即解析执行,执行完成之后删除。其中mycallback是本地的函数,这个函数接受参数用于使用参数。
CORS 后台允许跨域
在后台添加允许跨域:“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
第三方(也就是代理服务器)
文章https://m.imooc.com/article/288397中是这样说的:打破不同源的限制,我只要让它同源就可以了,比如要我的静态页面是 http://a.com/index.html 动态ajax请求访问的是http://b.com/api/***
我只需要将对应的服务部署在不同的机器上,然后使用一个公共的c.com的域名作为nginx反向代理的入口域名,在将静态服务和动态服务分别挂在后面的被代理局域网服务器内,修改配置
上一篇: 记录一些可能会用到的sql语句
下一篇: proxy解决跨域 一些配置问题