解决跨域的九种方法
发布日期:2022-02-22 16:04:48 浏览次数:6 分类:技术文章

本文共 2615 字,大约阅读时间需要 8 分钟。

同源策略请求:同源是浏览器的概念,指 协议,域名,端口号相同。 ajax(异步无刷新) / fetch

前后端分离导致跨域(非同源策略请求)

  • 前端:web服务器,请求资源文件 , 资源服务器:图片,音视频
  • 后端:数据服务器,处理业务逻辑和数据接口

一、jsonp

原理:基于script 标签 src属性 ,发送请求时,把本地函数作为回调函数传递给服务器,服务端接收并返回处理完成的数据,浏览器接收到响应数据,执行该函数。

前端:

//请求后台接口,将函数名作为参数传递给后台。 src不受同源策略的限制
   

服务器端:

//接收客户端的请求callback = func//准备数据data = {
   ...}//给客户端返回string类型的数据'func('+JSON.stringify(data)+')'

jsonp跨域原理

缺点:jsonp只能处理get请求。url传递数据可能被劫持(拦截响应),导致数据不安全(可能携带木马程序)不安全;有缓存,大小限制。

jQuery提供(内部封装)了jsonp的处理方式

前端:

$.ajax({
   
method:'get',
url:'http://127.0.0.1:8001/list'
dataType:'jsonp',//添加dataType属性,值为jsonp则执行的是JSONP请求
success:res=>{    console.log(res);}})

服务端:Node+express实现

let express = require('express');let app = express();app.listen(8000,()=>{
   console.log("服务器启动...")});app.get('/list',(req,res)=>{
   
let {    callback} = req.query;//解构赋值获取get请求传递的回调函数(请求参数)
let data = {    code:0,message'请求成功'};//返回给客户端的数据
res.send(`${
 callback}(${
 JSON.stringify(data)})`);
//发送数据给客户端  '函数名(参数)'})

发送请求
响应
浏览器拿到返回结果后,会把该全局函数执行,全局函数执行时会把success函数执行

二、CORS跨域资源共享

原理:客户端发送ajax/fetch请求,服务端设置相关头信息(需要处理options试探性请求)

客户端 axios直接发送请求,浏览器报错:No 'Access-Control-Allow-Origin' header is present on the request resource.

需要在服务器端(node + express使用中间件实现)设置请求头允许跨域
设置请求源地址
缺点:写 * 支持多源,但是不安全;一旦写 * 就不允许携带cookie
修改完成配置需要重启后端服务

三、基于http proxy实现跨域请求

配置webpack webpack-dev-server

webpack.config.js文件devServer:{
   
port:3000,//端口号
progress:true,//显示加载进度
contentBase:'./build',//指定访问的静态资源目录
proxy:{    //代理
'/':{    
target:'http://127.0.0.1:3001',//所有 / 请求都转到target下请求
changeOrigin:true //允许跨域
}
}}

部署上线 跨域时一般会用node写中间层

四、nginx反向代理

不需要前端代码,只需要服务端部署

需要linux服务器,安装nginx,配置web服务器…

五、postMessage

  1. a页面中 使用 postMessge()向b页面发送消息。使用 iframe 临时发送请求,并将iframe隐藏
   
    frameborder="0" style="display:none">
    
   
  1. b.html中 使用onMessage事件监听postMessage传递过来的信息 e.data
    数据处理完成,使用 e.source.postMessage(data,e.origin) 给a.html 返回响应数据(e.source 指 a.html,e.orign 指 源)
  1. a页面接收b页面处理完成返回的数据,script标签中添加:
//监听b页面传递的信息
window.onmessage = functino(e){    
console.log(e.data);
}

六、socket.io

客户端与服务端实时通信

前端:与当前域建立连接

   
    
   

服务器端:node+express实现,需要安装 server模块

//监听socket连接:server是服务器创建的服务socket.listen(server).on('connection',function(client){
   
//接收信息
client.on('message',function(msg){    
client.send(msg+'@@@');//向客户端返回处理完成的数据
});
//断开处理
client.on('disconnect',function(){    
console.log('client socket has closed!')
});});

七、document.domain+iframe

需要两个页面,适用于 主域名相同,子域名不同
父页面A:

   
    
   

子页面B:

八、window.name+iframe

需要三个页面 : A , B, proxy页面
A.html

B.html
proxy.html为空代理,什么都不用写

九、location.hash+iframe

需要3个页面: A , B , C ; A和C同源 ,A和B不同源
页面A:

   
    
   

页面 B:

   
    
   

页面 C:

实际开发过程中经常会遇到跨域的问题,在此总结了一些方法,希望对大家有所帮助,若存在有误之处,请予以指出,还望多多指教!

转载地址:https://blog.csdn.net/Conradine_Lian/article/details/107229450 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:关于HTTP协议的那些事儿
下一篇:axios 请求数据

发表评论

最新留言

初次前来,多多关照!
[***.67.29.132]2022年09月30日 08时13分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章