作为前端rd,在前后端数据交互时经常会碰到请求跨域,那么为什么存在跨域问题?有哪几种跨域解决方案?现在常用的webpack-dev-server是怎么实现的,它在vue-cli和creat-react-app里又是怎么使用的?
让我们带着问题继续往下看,文章中涉及到的demo已经放在github demo上,欢迎大家一起探讨。
为什么存在跨域问题
浏览器同源策略
在说跨域之前,我们需要了解下浏览器的同源策略
。
想了解更多关于同源策略的问题,请猛戳这里同源策略
怎么才算是跨域
了解了同源策略,那么哪种场景会出现跨域就很显而易见了。
图
只要 有一个不同,就是跨域。
跨域请求无返回结果的原因
我们都知道如果不进行跨域处理,直接发请求出去会报错,如下图这个错大家应该很熟悉。
问题1. 跨域请求报错的原因是什么呢?是浏览器没发请求出去,还是浏览器发请求出去了,但是服务器没返回?
问题2. 跨域请求为什么有的时候会发一条预请求(method是options的请求),有时候又不发预请求呢?
两种请求方式
ok,要回答这个问题,我们首先要知道浏览器的请求方式。浏览器将CORS请求分为两类:简单请求(simple request)和非简单请求(not-simple-request),简单请求浏览器不会预检,而非简单请求会预检。这两种方式怎么区分?请看下面这张图。
所以常用的get请求满足简单请求要求,就只发一条跨域请求出去。而post请求因为一般会设置Content-Type为application/json,就是非简单请求,需要发预请求。mdn上的这篇文章 👉HTTP访问控制(CORS) 写的很详细,感兴趣的同学可以看一下。
fetch
跨域的实现方案
JSONP
缺点:get 服务器支持
iframe
缺点:一级域名必须相同
CORS跨域资源共享
常用
代理转发
代理分为正向代理和反向代理,一句话概括就是代理客户端(浏览器)的是正向代理,代理服务端的是反向代理。
正向代理
在webpack还没兴起的时候,开发阶段常用的跨域方式是前端起一个node服务,页面访问对应的node服务,node服务再访问真实的服务器地址。
我们常用的webpack-dev-server就是正向代理,
反向代理
nginx + charles