天天看點

502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題

502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題
上篇 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');
});
           

我們來通路一下,可以拿到資料了。

502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題
  • 測試頁面

然後,我們寫一個簡單的 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>
           
502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題
  • 安裝 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);
           
502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題

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

當然,還可以更加真實一點,我們随便用一個域名測試一下。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。

502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題

這下是不是更加真實了。關于hosts 檔案的作用,就是我們輸入域名不是要需要經過DNS解析IP嘛,這個裡面就存了一些。首先自動從 Hosts 檔案中尋找對應的 IP 位址,一旦找到,系統會立即打開對應網頁,如果沒有找到, 則系統再會将網址送出 DNS 域名解析伺服器進行 IP 位址的解析。

還有一個問題,關于 HTTP 502 狀态碼,我是把接口服務停了,于是就報 502了。

502 proxy error解決方法_利用 Nginx 反向代了解決跨域問題

也不一定是網上說的什麼

連接配接逾時 我們向伺服器發送請求 由于伺服器目前連結太多,導緻伺服器方面無法給于正常的響應,産生此類報錯

那樣。

(完)

2019.11.30 補充

上面 Hosts 檔案那裡說錯了,輸入域名後并不是先自動從 Hosts 檔案中尋找對應的 IP 位址。而是浏覽器先從浏覽器的dns緩存中找,找不到再去 hosts檔案中找 :)

繼續閱讀