前端处理跨域问题

 

前端开发基本都会遇到跨域问题,我做项目的时候也不例外,为此我稍微整理了几个简单好用的跨域解决方案

 

 

跨域错误信息产生的原因

  • 浏览器端的限制(即浏览器的同源策略限制,此时服务端收到了请求并正确返回)
  • 发送的是 XMLHttpRequest 请求
  • 请求了不同域的资源

  只有同时满足了这三个条件,浏览器才会产生跨域错误

  同源策略限制内容有:
  Cookie、LocalStorage、IndexedDB 等存储性内容

  DOM 节点

  AJAX 请求不能发送


  但是img link script三个标签是允许跨域加载资源的

 

跨域错误处理方案

  1. JSONP
  2. 跨域资源共享CORS 

  3. webpack配置proxy反向代理

     

1.JSONP

  1)JSONP原理

  利用script元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)

  2)JSONP的流程

  声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。

然后创建一个请求,服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{“name”:“jianshu”}])。

  最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。

<script type="text/javascript">
function fn(data){
  alert(data.msg);
}
</script>
<script type "text/javascript" src "http://crossdomain.com/jsonServerResponse? jsonp=fn"
></script>

  其中 fn 是客户端注册的回调的函数,目的获取跨域服务器上的json数据后,对数据进行在处理。

最后服务器返回给客户端数据的格式为:

fn({ msg:'this is json data'})

 

2.CORS

  1)CORS原理

  整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

  2)CORS优缺点

  CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。

优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。

  3)CORS流程

  CORS只需要在服务器端做一些小小的改造即可 (在头信息之中,增加'Access-Control-Allow-Origin',若要带cookie请求:前后端都需要设):

例如:网站http://localhost:{{63342:0}}/ 页面要请求http://localhost:3000/users/userlist 页面,userlist页面返回json字符串格{name: ‘Mr.Cao’, gender: ‘male’, career: ‘IT Education’}

//在服务器端设置同源策略地址
router.get("/userlist", function (req,res, next){
  var user - {name:'Mr.cao' , gender: 'male', career: 'IT Education'};
  res.writeHeader (200,{ "Access-Control-Allow-Origin": ' http://localhost:{[63342:0]}'});
  res.write(JSON.stringify(user));   res.end(); });

 

3.反向代理

  1)原理

  在浏览器中创建了代理服务器,缺点渲染效率降低

  2)实现

   在webpack.config.js文件里配置:

 

const url = 'http://192.168.0.111:9999' //服务器端接口地址
module.exports = {
  //...
  devServer: {
    proxy: {
        '/api': {                //这里最好有一个 /
            target: url,         // 服务器端接口地址
            ws: true,            //如果要代理 websockets,配置这个参数
            secure: false,       // 如果是https接口,需要配置这个参数
            changeOrigin: true,  //是否跨域
            pathRewrite:{'^/api':''}
        }
    }
  }
};

 

此时访问的接口地址在本地被解析为localhost:8080/api/***

访问的真实地址是http://192.168.0.111:9999***

 

vue的反向代理处理跨域例子

了解更多关于Proxy代理配置

 

除了这三个处理跨域的方案之外,还有WebSocketpostMessage方案,感兴趣的可以到https://blog.csdn.net/qq_43239820/article/details/89186319了解。

 

posted @ 2021-07-26 10:04  不如饲猪  阅读(553)  评论(0)    收藏  举报