使用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跨域总结

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

(码云地址)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • 题目1.什么是同源策略? 同源策略(Same origin Policy): 浏览器出于安全方面的考虑,只允许与本...
    FLYSASA阅读 1,721评论 0 6
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,965评论 6 13
  • 什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
    他方l阅读 1,064评论 0 2
  • 什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
    Yaoxue9阅读 1,299评论 0 6
  • 原文地址:原文地址 什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 广义...
    C_Y大渔阅读 1,259评论 1 13