新手学跨域之代理/转发
- jsonp
- iframe
● document.domain
● window.name
● location.hash
● navigator (IE6 bug)
● postMessage - CORS
● XMLHttpRequest (modern browser)
● XDomainRequest (IE8+) - 图像Ping (略)
- flash (略)
- 代理/转发
● http-server
● webpack-dev-server
● nginx
以前写的这个系列的时候,是看了一些资料之后通过实操,从一个前端初学者的角度记录验证过程。
但是,在近年来的工作中发现用到的场景并不多,实际工作中大部分遇到的跨域问题还是在调用接口时。
虽然有了CORS方案,但是对我来说,CORS实际开发中并不友好。首先它不支持低版本浏览器,当然现在前端开发基本可以忽略这个问题了,更主要的是CORS是需要服务器配置的,而这个一般是后台同事负责。第一次接口请求报错了,提醒他们要加上允许请求的域,后来接口新增了新的请求方法或请求头字段,又要提醒他们,遇到有经验又有耐心的后台开发小哥哥还好,不然就等着吧。
我们回到本质,为什么会有跨域问题,原因是浏览器的同源策略。所以如果调用的接口与页面同域或调用接口的不是浏览器就没有跨域问题了。现在把两者结合起来就可以实现跨域请求,即前端把请求发送给页面服务器,页面服务器请求接口服务器,拿到数据后再返回给前端,这里页面静态服务器充当了代理/转发的角色。
现在我们具体看看怎么实现代理/转发,假设要请求的接口为https://api.yyy.com/data.php
http-server
文档:
https://www.npmjs.com/package...
现在前端开发一般会在本地使用Node开启静态服务器,可以用http-server
这个包创建一个简单的静态服务器,加上选项-P
或--proxy
即可实现接口代理/转发
http-server -P https://api.yyy.com
现在为当前目录开启了一个静态服务器,前端直接请求即可拿到接口数据
fetch('data.php').then(console.log)
请求当前data.php
相当于请求https://api.yyy.com/data.php
,并且没有跨域问题。
http-server
优点是简单快捷,缺点是不够灵活,且不能自动监听代码改动并刷新页面。BrowserSync
可能是更好的选择。
webpack-dev-server
文档:https://webpack.js.org/config...
http-server
适合本地写些简单页面、小demo,而我们开发复杂些的项目,比如基于Vue.js
、React
等来构建项目一般会用到webpack,并且在开发阶段使用webpack-dev-server
,这里只介绍它的代理部分,它的代理实现是基于http-proxy-middleware
封装。
在webpack.config.js
里配置
devServer: { // ... proxy: { '/api': { // 如果是匹配所有接口请求可以用'**' target: 'https://api.vczhan.com', changeOrigin: true, pathRewrite: {'^/api' : ''} // 本地请求中加上了api以区别不同接口请求,但真正的接口是没有的,所以这里对它重写 } } }
前端请求
fetch('api/data.php').then(console.log)
这里请求api/data.php
会转发到https://api.yyy.com/data.php
。
nginx
前端代码打包后传到服务器上,需要一个web服务器,这样才能访问页面,这里选择nginx
,它既轻便又强大,可配置的规则很多,这里只展示最简单的代理配置
server { listen 80; server_name xxx.com location /api/ { proxy_pass https://api.yyy.com/; # 转发到api.yyy.com # proxy_pass https://api.yyy.com; # 转发到api.yyy.com/api/ } }
同样的请求http://xxx.com/api/data.php
会转发到https://api.yyy.com/data.php
。
虽然也涉及了服务器配置,但基本只要配置一次就行了,一般web页面的服务器,会给前端同学权限吧。