502 proxy error解决方法_利用 Nginx 反向代理解决跨域问题

92765ff8f4f0bd4f1b8fa2d4d8a73290.png
上篇 JSONP 的文章里提到过利用 Nginx 也可以解决跨域问题。趁着自己以前没有接触过 Nginx,熟悉了一下,顺带写了一个非常非常简单的 demo 实验下。

正向代理和反向代理

提到代理,肯定要说一下这两个的区别。

举个正向代理的例子:我打球累了走不动了,找看球的小朋友帮我去旁边的商店买瓶水。商店老板是不知道到底是谁需要喝水的,隐藏了客户端。当然,小朋友可以告诉老板就是那个打球像蔡徐坤的人要喝水。还有,VPN 就是正向代理。

反向代理的例子:我打球累了,找看球的小朋友要瓶水喝(当然我肯定会给钱的:D)。我不需要知道小朋友的水是从旁边的商店还是两公里外的超市买的。隐藏了服务端。还有,我们连好了 VPN 访问谷歌的时候,浏览的那些页面,我们是不会知道具体是哪台服务器的资源。

具体步骤

  • 服务接口

既然请求,肯定需要先写一个服务接口,我们用 node 起一个服务:

  // index.js
const http = require('http');
const fs = require('fs');
const url = require('url');

const server = http.createServer(function (req, res) {
  if (req.url === '/favicon.ico') {
    return;
  }
  const parseUrl = url.parse(req.url, true);
  console.log('parseUrl', parseUrl.pathname)
  if (parseUrl.pathname === '/api/getList') {
    const list = {'a': 1, 'b': 2}
    res.writeHead(200, {'content-Type':'text/html;charset=UTF-8'})  
    res.end(JSON.stringify(list))
  }else {
    res.write(`
    port: 666
  `)
    res.end()
  }
});
server.listen(666, function () {
  console.log('server is starting on port 666');
});

我们来访问一下,可以拿到数据了。

0f1d715cc311e3914ef7d4abadf32c79.png
  • 测试页面

然后,我们写一个简单的 ajax 请求页面。你可以本地用http-server启动访问下,可以发现请求跨域了:

<html>
<head>
  <title></title>
</head>
<body>
  <button onclick="sendAjax()">sendAjax</button>
<script type="text/javascript">
  var sendAjax = () => {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'http://localhost:666/api/getList', true);
      xhr.send();
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
          console.log(xhr.responseText);
        }
      };
  }
</script>
</body>
</html>

d0adc5dcdc3701eb1933c1d40905d57a.png
  • 安装 Nginx

这个时候,你可以通过设置响应头来允许跨域。或者用 Nginx 来解决这个问题了。首先肯定需要安装 Nginx。这个按照对应的平台安装就行了。

brew update
brew install nginx
nginx
nginx -s reload // 重启
  • 配置

然后我们配置一下代理,这个意思就是我们请求中有 api 这样的就会代理到 http://127.0.0.1:666,所以我们只要访问 http://localhost:9999/api/getList 这个不跨域的接口,然后就会由服务器反向代理到 http://localhost:666/api/getList。

        listen       9999;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /api/ {
            proxy_pass http://127.0.0.1:666;
        }

配置好之后我们需要重启一下 Nginx 服务。注意一点,重启时可能会报这么一个错误:

nginx: [error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)

这是 sudo nginx -s stop 这个命令会删除 pid 文件,可以执行 sudo nginx 重新添加这个文件。

  • 测试结果

这个时候,我们不用绝对地址了,我们把ajax请求里面的接口换成相对地址:

// xhr.open('GET', 'http://localhost:666/api/getList', true);
xhr.open('GET', '/api/getList', true);

86ae763e0a7870bd70c5e88f57b51375.png

美滋滋,这就不跨域了呢。

当然,还可以更加真实一点,我们随便用一个域名测试一下。Nginx 重新配置下:

        listen       80;
        server_name  yumingtest;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /api/ {
            proxy_pass http://127.0.0.1:666;
        }

然后在 hosts 文件里面添加这条:127.0.0.1 yumingtest.com,重启下 Nginx。

07372c650198e1f97ef184ac391a0d0f.png

这下是不是更加真实了。关于hosts 文件的作用,就是我们输入域名不是要需要经过DNS解析IP嘛,这个里面就存了一些。首先自动从 Hosts 文件中寻找对应的 IP 地址,一旦找到,系统会立即打开对应网页,如果没有找到, 则系统再会将网址提交 DNS 域名解析服务器进行 IP 地址的解析。

还有一个问题,关于 HTTP 502 状态码,我是把接口服务停了,于是就报 502了。

e1ded719fcdd9e481789b77c6534e8e2.png

也不一定是网上说的什么连接超时 我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错那样。

(完)

2019.11.30 补充

上面 Hosts 文件那里说错了,输入域名后并不是先自动从 Hosts 文件中寻找对应的 IP 地址。而是浏览器先从浏览器的dns缓存中找,找不到再去 hosts文件中找 :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值