跨域问题基于浏览器的同源策略,即协议,域名,端口都一致浏览器才能发送请求,而服务端发送请求没有跨域的问题
使用 webpack 进行开发解决跨域问题主要有以下方法:
通过配置服务器代理
不能操控后端代码时(比如前后端联调)可用
在配置文件 webpack.config.js 中添加 devServer 配置,然后配置它的 proxy 属性,webpack-dev-server 在起服务后,会把匹配的本地请求转到 proxy 里配置的服务器上去请求,通过服务端的转发,实现跨域
例如:
- 前端服务端口(dev-server)8080
- 联调的后端端口:3000
如果在前端发送请求xhr.open('GET', '/api/user')实际上完整的请求 url 是 http://localhost:8080/api/user,直接请求报错,因为前端服务端口没有这个接口
现在给 devServer 配置 proxy
devServer: { |
通过 webpack-dev-server 起服务器, 在遇到 /api/user 这种以 /api 开头的请求的时候,它不再往本地 localhost:8080发了,而是向对应的http://localhost:3000发请求。这是一种后端而非浏览器的的请求转发,有跨域问题。这个时候,虽然在浏览器查看前端发的请求地址是http://localhost:8080/api/user,但其实它的背后真正获取响应的请求是http://localhost:3000/api/user
实际后端接口没有类似 api 这种统一前缀,为了方便配置,proxy 提供了 pathRewrite参数改写请求路径
devServer: { |
此时前端发送请求xhr.open('GET','/api/user')
前端请求的完整 url http://localhost:3000/api/user
经过代理后最终请求 url http://localhost:3000/user
在 dev-server 内 mock 数据
直接使用 webapck-dev-server mock 数据,mock 接口和前端符合同源策略
webpack-dev-server 内部其实是自己起了一个express来做服务
webpack 的 devServer 配置提供了一个before方法,在启动服务之前,这个方法会被执行,我们可以把我们 mock 数据的逻辑写在这里
devServer: { |
before 方法会传一个参数 app 供我们使用,这个参数就是 webpack-dev-server 内部起的express对象
在服务端启动 webpack
提供接口的服务端代码:
// server.js |
把 webpack 构建放在服务端 server.js 中,服务器和前端共用一个地址;
通过服务端起 webpack 需要中间件 webpack-dev-middleware,整体逻辑为:
获取 webpack 模块 -> 获取 webpack 配置文件 -> 将配置文件传给 webpack 执行,获得compiler 实例 -> 把 compiler 实例传给 webpack-dev-middleware 中间件,然后整个交给express 作为 express 中间件执行 -> done
// server.js |
此时通过 node server.js起服务器和 webpack 前端构建
总结
第一种方法是我们提倡的跨域配置,配置代理,首选推荐
第二和第三种方法其实是在你能控制后端工程的情况下,把前后端工程合并成一个工程了,区别是第二种方法相当于把后端接口移到前端工程来起,第三种方法是把前端工程构建移到后端工程来起。