跨域的这三种解决方案你知道吗?



什么是跨域?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

说到这里,大家肯定会好奇,那么什么是同源策略呢?

所谓同源就是指:域名,协议,端口均相同


在这里插入图片描述

http://www.123.com/index.html 调用 http://www.123.com/server.js(非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.js(域名不同,所以跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.js(子域名不同,所以也是跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.js(端口不同,所以也是跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.js(因为协议不同,所以也跨域了)

注意:localhost 和 127.0.0.1 虽然都指向本机,但是也是属于跨域


跨域的三种解决方案


- JSONP


由于同源策略只对 js 代码进行限制,所以,我们可以通过其他的方式来绕过同源策略的限制,从而来发送请求。


最后发现浏览器只对 ajax 请求有同源请求限制,而对 script 标签 src 属性、link 标签 href 属性和 img 标签 src 属性没有这种限制。因此就有了一种解决跨域的方法,以下介绍了两种方式中的 jsonp 来解决跨域:


1. 使用原生 js 来书写 JSONP解决跨域问题


这里主要是创建了一个 script 标签,并且设置它的 src 属性为我们所要请求的服务器地址,然后将这个 scritp 标签添加到页面中,这样就完成了一次请求的发送。值得提出的是:在服务器端返回的数据要以 js 代码的形式返回。

let script = document.createElement('script');
script.setAttribute('src','http://127.0.0.1:3000');
document.getElementsByTagName('head')[0].appendChild(script);
document.getElementsByTagName('head')[0].removeChild(script);

注意:上面的最后一行代码,是因为你发送了一次请求它就会添加一条 script 标签,在实际项目中,请求的次数肯定不止一次,所以如果不删除,就会有很多条 scritp 标签,导致代码冗余。


2. jQuery 中使用JSONP来解决跨域


主要思路:在请求地址后面添加一个 ?callback=?,将 ajax 方法中的 dataType 设置为 jsonp,最后服务器会接收一个由 jquery自动生成 callback 函数,将要返回的数据放在这个函数中。
$.ajax({
   url : 'http://127.0.0.1:3000/stu?callback=?',
   dataType:'jsonp',
   success : function(data){
     console.log(data);
   }
 })

- CORS


CORS 方法可以说是解决 ajax 跨域方案中最为优雅的,最为简单的方法

实际上,跨域的请求会正常发送到服务器,服务器也会正常接收到请求并且也会正常的返回响应,那为什么还会出现跨域呢?那就是因为浏览器的同源策略,导致浏览器不会将返回的数据交给 js 来执行。

// 创建一个中间件,这个中间件的作用是允许跨域
const allowCorssDomain = function(req,res,next){
  // 我们在这个中间件里面主要是设置响应头
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept");
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header('Access-Control-Allow-Credentials','true');
  next();
}

app.use(allowCorssDomain);

CORS 方法其实很简单,只需要在响应头里面添加一些键值对即可,如以上代码


- 搭建代理服务器


总的来说导致跨域的问题就是因为浏览器的安全策略的限制,但是如果是服务器向服务器发送请求,就不会有这样的安全限制了

所以,就有了代理服务器这么一说,可以先让 ajax 请求同源的代理服务器,再由代理服务器向目标服务器发送请求,这样就圆满的解决了跨域的问题


具体操作如下:

首先我们需要再创建一个服务器。
代理服务器可以使用express proxy-server来创建的。

在这里插入图片描述

接下来需要对代理服务器进行一个配置,需要安装一个中间件

npm i http-proxy-middleware

具体配置如下:

// 对中间件进行一个配置
const options = {
  target : 'http://127.0.0.1:3000',  // 目标服务器的地址
  changeOrigin : true , // 是否可以改写 url
  pathRewrite : {
    // 定义你的改写规则
    '^/api' : '/'
  }
}

接下来对这个中间件进行注册

// url 以api开头的,要用 proxy 这个中间来进行处理
app.use('/api',proxy.createProxyMiddleware(options));

最后,在客户端发送请求的时候,就要在前面添加 api ,如下:

 $.ajax({
   url : '/api/stu', // 添加 api 这个前缀,代表该请求要转发
   type : 'get',
   success : function(data){
     console.log(data);
   }
 })
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值