【原理向】关于前端跨域的理解及其解决方法

169 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天

在了解跨域之前首先要知道什么是一个网站的源? 源=协议+主机+端口

什么是跨域问题

所谓跨域就是由于源的不同对ajax请求造成的影响;而解决跨域问题一般有三个途径:

如何解决跨域问题

1. CORS 跨域

``跨源资源共享``——是一种基于HTTP头使它允许服务器标示除了它自己以外的其它(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源的操作。

为什么要使用CORS?

  1. CORS克服了ajax对于请求不同源的限制
  2. CORS需要浏览器和服务器同时支持,整个 CORS通信过程,都是浏览器自动完成不需要用户参与,对于开发者来说,CORS的代码和正常的 ajax` 没有什么差别,浏览器一旦发现跨域请求,就会添加一些附加的头信息
  3. 该种跨域请求一般分为两种,简单类型(包括HEAD、POST、GET)和非简单类型(比如PUT

个人理解CORS是通过请求方式的不同向请求添加关键字段以此匹配然后跨过去 添加的字段是那个Access-Control-Allow-origin,然后浏览器会根据这个字段去匹配,来确定是否允许该域名跨域 因此可以将CORS理解为通过匹配解决跨域

2. 代理 ——什么是代理?

代理就是一个服务,该服务的作用就是:监测本地的接口,当接口为需要访问外网的接口时,代理替你访问这个接口并把返回值返回给当前网页。

通过代理解决前端跨域问题

webpack中proxy(只用于开发阶段)代理配置

场景1:【域名不同】将/api/xxx被代理请求到http://localhoost:3000/api/xxx

可以在proxy里面配置多个服务器路由

// vue 的开发服务器代理配置
// 找vue.config.js
//添加类似如下的代理配置,**vue2,vue3的位置不一样,
//vue2是在config/index.js,vue3是在vue.config.js中;
//vue2中使用proxyTable配置代理,vue3使用proxy配置代理。
//注意,如果你配了 proxy,发请求的时候,就不要在 axios 里面用全路径,请去掉 host。
module.exports = {
  devServer: { // 配置开发服务器,如果向不同的服务器发送请求可以配置多个
    proxy: { // 配置代理
      "/api": { // 若请求路径以 /api 开头
        target: "http://dev.taobao.com", // 后台接口域名,将其转发到 http://dev.taobao.com
        pathRewrite: { // 把/api换成空字符串(因为真实的后台接口路径上没有/api) '^/api': '' } // 地址变成 // http://xxxx.com/xxxxxxx
      },
    },
  },
};

前端代理转发请求

image.png

场景2:使用webpack向不同的服务器发请求

只需要配置多个devServer即可向不同的服务器发送请求

场景3:【协议不同】想要支持https(超文本传输安全协议)

默认情况下不接受运行在https上,且使用了无效证书的后端服务器,这个时候就需要前端人员配置解决

module.exports = {
    //...
    devServer: {
        proxy: {
            '/api': {
                target: 'https://other-server.example.com',
                secure: false//是否验证SSL Certs
            }
        }
    }
};

使用webpack中的proxyTable解决跨域(一般在早期Vue2使用,但是可以帮助理解)

使用vue搭建的项目在本地与后端联调时,因为是使用node服务器,IP与后端不一致,所以会产生跨域问题(前后端域名不同造成),需要使用如JSONP、跨域代理等手段进行跨域请求,而vue已经帮我们配置好了,只需要设置一下proxyTable就行。

proxyTable原理

浏览器是禁止跨域的,但是服务端不禁止,在本地运行npm run dev等命令时实际上是用node运行了一个服务器,因此proxyTable实际上是将请求发给自己的服务器,再由服务器转发给后台服务器,做了亦曾代理,因为不会出现跨域问题。

3.JSONP

为什么要使用JSONP?

1. 兼容性好,能兼容老版本浏览器

什么是JSONP?

像ajax但不是ajax,

说他像是因为他和ajax一样是请求一个url拿到一个callback函数,

不同的是:ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加script标签来调用服务器提供的js脚本。

使用XMLHttpRequest (XHR)对象可以与服务器交互。您可以从URL获取数据,而无需让整个的页面刷新。这使得Web页面可以只更新页面的局部,而不影响用户的操作。XMLHttpRequest在ajax编程中被大量使用。

了解XMLHttpRequest戳->blog.csdn.net/qq_27870421…]

JSONP跨域的原理

  1. 使用script 标签发送请求,这个标签支持跨域访问

  2. 在script 标签里面给服务器端传递- 一个 callback

  3. callback 的值对应到页面一定要定义一个全局西数(为什么是全局?因为服务端接收到callback 西数后会返回页面中的script中去找,如果不写在全局作用域中根本找不到)

  4. 服务端返回的是一个函数的调用。调用的时候会把数据作为参数包在这个西数里面。

JSONP实战代码实现请参考www.pipipi.net/questions/1…