一、同源策略
- xhr对象无法跨域请求文件。通俗讲就是“浏览器”给js发送请求的限制,你只能给自己域名下的服务器发送请求,不能向别人家的服务器发送请求。
- 当ajax请求的url中的传输协议、域名、端口号,有任意一个不同时,就会触发同源策略
二、jsonp
1、早期常用的一种解决跨域请求问题的方案,至今还在使用;
原理是不用xhr对象发送请求了,我们用标签的src发送请求。
2、script的src属性不受浏览器同源策略限制,可以通过该属性进行跨域请求,只要返回的是一个正确的js语法的代码(字符串),那么就可以执行。
jsonp技术就是让后端返回一个函数调用,在函数调用中把数据作为实参给前端定义好的形参,从而实现数据的接收。
3、jsonp跨域解决方案:
- 声明一个全局函数,函数的形参就是要请求的数据
- 动态创建script标签,利用script标签的src属性跨域请求数据,将callback=声明的函数名 拼接在地址栏中传递给后端
- 后端接收到请求后将请求的数据作为实参返回一个该函数的调用
- 前端通过声明的全局函数对请求的数据进行处理
var btn=document.querySelector('input');
//声明全局函数
function callBack(data){
console.log(data);
}
btn.onclick=function(e){
//动态生成script标签
var script=document.createElement("script");
//设置src属性
script.src="http://127.0.0.1/text.php?callback=callBack";
//将创建好的标签放入文档中
document.body.appendChild(script);
//当script加载完成后移除script标签
script.onload=function(e){
document.body.removeChild(script);
}
}
4、案例:百度关键字联想
<script src="ajax.js"></script>
<script>
//借口路径:https://www.baidu.com/sugrec
//接口参数:prod=pc,wd:关键字,cb:回调函数名
var inp=document.querySelector("input");
var ul=document.querySelector("ul");
inp.oninput=function(e){
ajax({
url:"https://www.baidu.com/sugrec",
data:{
wd:this.value,
prod:"pc"
},
jsonp:"cb",
dataType:"jsonp",
callback:function(res){
renderRes(res.g);
}
})
}
function renderRes(list){
//list有两种情况
//1:数组,渲染到页面上
//2:undefined 清空渲染的结果
if(list instanceof Array){
ul.innerHTML=list.map(item=>{
return `<li>${item.q}</li>`;
}).join("");
}else{
ul.innerHTML="";
}
}
</script>
三、cors
- cors 跨域资源共享
- cors跨域是后端响应头的配置,在后端语言中配置的
- cors跨域是副作用最小的,在应用场景中使用最多的跨域方式;如果后端是我们自己编写的,那么我们一定要优先选择cors跨域方式
==header(“Access-Control-Allow-Origin:*”);
==header(“Access-Control-Request-Methods:GET, POST,PUT,DELETE,OPTIONS”);
==header(‘Access-Control-Allow-Headers:x-requested-with,content-type,test-token,test-sessid’);
四、proxy
1、 proxy 代理跨域(让服务器代理跨域)
2、解决原理:
- 在浏览器同源设置一个代理服务器
- 把本该发送给目标服务器的请求发送给代理服务器
- 由代理服务器转发请求给目标服务器,目标服务器会把响应给代理服务器,代理服务器再把响应给到浏览器
3、怎么进行代理配置
只要是服务器都可以代理
但是apache代理https不是免费的
这里使用nginx服务器,他代理http和https都是免费的
- 打开nginx配置文件(nginx-conf)
=>大概在56行左右有一个server
=>在server里面书写代理配置 - 代理配置
=>/aaa是自己定义的,名字可以是任意,这个就是代理标识符
=>斜线必须有,{}里面的地址就是要跨域请求的目标地址
location = /aaa{
proxy_pass http://127.0.0.1/proxy.php;
}