使用proxy来解决跨域请求.

[之前的那篇博客]

介绍了 corsjsonp 处理跨域的情况.

  • cors 通过后台服务器在响应流里设置 Access-Control-Allow-Orign:*,来解决跨域问题,而且支持 GET,POST等简单请求. put,delete 等复杂请求(会首先发送一个请求预检 options(204))
  • jsonp 则是利用浏览器可以从异源下载script的方式,动态创建一个script标签,并设置src=xxx?callback=fn的方式来请求一个script标签.后台服务器需要获取到这个callback参数,然后像前台响应数据. (但是jsonp 支持 GET 请求)

上述两种方案,都可以解决跨域请求.

但是都一个前提:

需要后台的配合和参与.

如果,后台不是我们写的,也没有办法让写后台的人去配合我们呢?

可以使用 proxy 代理的方式,结束上述产生的跨域请求问题.


使用 proxy 解决跨域的请求的问题.

一般思路是,我们自己写一个服务器.

本地的网站请求的数据会通过我们的服务器进行代理,由服务器发送真实的数据请求到目标数据后台.

目标数据后台把数据返回给我们自己的后台,在经由我们自己的后台转发给我们自己的前台.

image.png

原理很简单

浏览器有同源策略,但是服务器没有.

既然了解了基本原理,就可以开始例子了.


写一个自己的后台做跨域处理.

例子总览:

  • 自己的网站端口号是: http://127.0.0.1:12345
  • 自己网站后台有一个 /proxy 的路由用于处理跨域数据请求.
  • 别人网站提供了一个数据接口,但是端口号是:54321 -> http://127.0.0.1:54321/data.json
  • 自己的网站请求 data.json 才用自己服务器代理的模式 http://127.0.0.1:12345/proxy?http://127.0.0.1:54321/data.json
  • 自己的服务器解析路径获取到真是的数据连接 http://127.0.0.1:54321/data.json
  • 自己的服务器由于没有同源策略的限制,所以可以直接发送这个请求,并或者数据返回值.
  • 最后经由自己的服务器返回给自己的前端浏览器.

server端的项目目录

image.png

server.js 提供 index.html 静态页面服务器以及 /proxy 跨域代理请求服务.

const http = require('http')
const fs = require('fs')

http.createServer((request, response) => {
  if (request.url.endsWith('.html')) {
    fs.readFile('./index.html', 'utf-8', (err, file) => {
      if (err) response.end(err.message)
      response.end(file)
    })
  } else if (request.url.startsWith('/proxy')) {
    // 需要代理请求
    // response.setHeader('charset','utf-8')
    const originJsonURL = request.url.split('?')[1]
    console.log(originJsonURL)
    // http.get(originJsonURL, (res) => { 
    //   res.pipe(response)
    // })
    http.get(originJsonURL, (data => { 
      data.pipe(response)
    }))
  }

}).listen(12345, (err) => { 
  if (err) console.log(`服务器启动失败:${err.message}`)
  console.log(`服务器启动成功,正在监听:12345`)
})

index.html

axios.get('/proxy?http://127.0.0.1:54321/data.json')
    .then(response => {
      console.log(response.data)
      document.querySelector('.content').innerText = JSON.stringify(response.data)
})

访问链接是:

/proxy?http://127.0.0.1:54321/data.json

经由自己后台服务器再次向 http://127.0.0.1:54321/data.json 并获得返回数据.

启动一个端口号为 54321json 服务器.

image.png

最后在index.html 中查看测试结果.

image.png

发现正确返回了 http://127.0.0.1:54321/data.json 的数据.

就表示自己写的代理服务器跨域请求数据成功了.
`


使用 Nginx 实现跨域请求.

使用 Nginx 实现跨域请求和上述的原理一模一样.

只不过 Nginx 帮助我们做了服务转发请求这件事情.

具体流程如下:

  • 将自己的前端资源部署在 Nginx 的 http 服务器.
  • 设置网站资源根目录.
  • 设置监听接口.
  • 设置 proxy_pass 代理转发规则.

具体操作如下:(MAC 系统中)

  1. 首先,要查看本机是否安装了 Nginx
nginx -v
image.png
  1. 打开 nginx 的配置文件.

mac 系统在目录 /usr/local/etc/nginx/nginx.conf

  1. 在里面找到 http 节点
 server {
       charset utf-8;
        # 监听的端口号 
        # http://127.0.0.1:11111/
        listen       11111;
        server_name  127.0.0.1; #监听的服务地址
        #charset koi8-r;
        # 配置自己的静态网站路径,并指定网站的根目录
        location / {
            root   /Users/relax/Desktop/代码/前端学习/同源策略和跨域/nginx反向代理处理跨域/html;
            index  index.html index.htm;
        }

        # 匹配一 /apis开头的请求正则表达式.比如 http://127.0.0.1:11111/apis/data.json -> http://127.0.0.1:22222/apis/data.json
        location ^~ /apis {
          proxy_pass http://127.0.0.1:22222/apis;
        }
    }

注意:

我们这里配置了proxy_pass 规则.
在这个例子中,如果我们访问 http://127.0.0.1:1111/api 将被 Nginx 自动转发到 http://127.0.0.1:22222/api 下.
所以,我们在请求数据时,仍然写自己的网站的请求地址,而不是实际的请求网站的地址.

  1. 启动或者重新加载 nginx
sudo nginx // 启动
sudo nginx -s reload // 如果修改了配置文件,使用这个命令.
  1. 启动 22222 端口号提供的json服务器.
cd data.json dir 的目录
http-server -p 22222

  1. 打开 Nginx 提供的http服务的index.html,访问并跨域跨域请求数据.
image.png

同样成功的完成了跨域请求.


使用proxy跨域总结

  • 不要觉得跨域是个什么很高大上和难以理解的东西.浏览器自己搞了个同源策略而已.自己在那玩而已.
  • 服务器又不是浏览器,什么请求都可以发,自然就不存在所谓的跨域限制了.

(码云地址)

你可能感兴趣的:(使用proxy来解决跨域请求.)