一. 跨域的概念
同一时间,一个页面存在访问多个主机的情况,且每个主机之间,协议,主机,端口其中之一不相同。
同源策略:
两个主机,如果是协议,主机或域名,端口,其中之一不一样,就违反了同源策略
同源策略的限制:
不能发送ajax请求
不能跨域操作DOM等
不能跨域操作本地存储(cookie,localstorage,sessionstorage)
同源策略的产生最初是为了预防XSS和CSRF跨域脚本攻击。
二.跨域请求分类
1.简单跨域请求
请求类型:只支持GET,HEAD,POST
内容类型: x-www-urlencode,form-data,text/plain
请求只发一次
2.非简单跨域请求,范围比简单跨域请求更大
请求类型都支持
内容类型都支持
请求发两次,第一次是OPTIONS类型的请求,用于验证服务端是否允许跨域,如果允许,再发第二个请求,第二次就会发送数据。
三.JSONP方式解决跨域问题
client客户端:
<script> //;handlejsonp({"name":"jsonp"}) function handlejsonp(data){ console.log(data); } </script> <script type="text/javascript" src="http://localhost:3000/jsonp?callback=handlejsonp"> </script>
api服务端:
router.get('/jsonp', async (ctx, next) => { let cb = ctx.query.callback||"callback"; let param = {name:"jsonp"}; //";"+cb+JSON.stringify(param); //模板字符串 let jp = `;${cb}(${JSON.stringify(param)})`; //设置响应头,告诉浏览器这是一个js脚本内容 ctx.type="text/javascript" ctx.body = jp; })
四.CORS解决方案
CORS跨域资源共享,只需要在后端设置3个基本响应头,就可以允许跨域
客户端:
<script> //发送简单请求 function sendEasyAjax(){ let req = new XMLHttpRequest(); req.open("GET","http://localhost:3000/json"); req.onreadystatechange=function(){ if(req.status==200&&req.readyState==4){ console.log(req.responseText); } } req.send(); } sendAjax(); //发送非简单请求 function sendAjax(){ let req = new XMLHttpRequest(); req.open("POST","http://localhost:3000/noeasy"); req.onreadystatechange=function(){ if(req.status==200&&req.readyState==4){ console.log(req.responseText); } } let jsonParam = JSON.stringify({"classname":"jy001","classcount":36}); req.send(jsonParam); } </script>
服务端只需要在app.js入口文件中设置:
app.use(async (ctx, next) => { ctx.set("Access-Control-Allow-Origin","*"); ctx.set("Access-Control-Allow-Headers","Content-Type,Authorization"); ctx.set("Access-Control-Allow-Methods","OPTIONS,GET,POST"); //对OPTIONS类型的请求,直接返回成功状态即可, //因为它只是用于验证是否支持跨域 if(ctx.method=="OPTIONS"){ ctx.status=200; return; } //记得加上next()否则请求流程会中断 await next(); })
最后
如果对您有帮助,希望能给个👍评论收藏三连!
博主为人老实,无偿解答问题哦❤