乐趣区

新手学跨域之代理转发

  • 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.jsReact 等来构建项目一般会用到 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 页面的服务器,会给前端同学权限吧。

退出移动版