前端跨域解決方案--代理


代理服務器監聽本地請求,然后由代理服務器轉發請求到目標服務器,因為服務端不存在同源策略,所以不存在跨域問題。

1. webpack-dev-server

項目如果有使用 webapck 的開發服務器,那么只需要配置一下代理(proxy)就可以輕松實現跨域,如下

``` 
devServer: {
  contentBase: [
    path.join(__dirname, '../public'),
    path.join(__dirname, '..')
  ],
  hot: true,
  host: '0.0.0.0',
  disableHostCheck: true,

  // 代理相關
  proxy: {
    '/api/**': { // 匹配代理路徑規則,僅代理接口請求,頁面和靜態資源請求不需要
      target: 'http://test.com', // 后端提供的目標接口地址
      pathRewrite: {'^/api': ''}, // 重寫路徑
      secure: false, // 接受 運行在 https 上的服務
      changeOrigin: true // 默認false,是否需要改變原始主機頭為目標URL
    }
  }
}

```

2. node.js

http-proxy-middleware 中間件實際就是將 http-proxy 封裝,使用起來更加方便簡單。

``` 

const express = require('express');
const app = express();
const { createProxyMiddleware } = require('http-proxy-middleware');

const port = 8888; // 代理服務端口

app.use('/', createProxyMiddleware({
    // 代理跨域目標接口
    target: 'http://test.com',
    changeOrigin: true,
    // pathRewrite: {
    //     '^/api' : '/',     // 重寫請求
    // },
    // 修改響應頭信息,實現跨域並允許帶cookie
    onProxyRes: function(proxyRes, req, res) {
        const origin = req.headers.origin || '*'  // 當前端只跨域不帶cookie時,可為*
        res.header('Access-Control-Allow-Origin', origin); 
        res.header('Access-Control-Allow-Credentials', 'true'); //  它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。
    }
}));

app.listen(port);
console.log(`Proxy server is listen at port ${port}...`);

```

3. nginx

1). 瀏覽器請求 nginx, 然后 nginx 代理去訪問前端資源和后端接口,因為對於瀏覽器來說,接口和頁面是同一個域名和端口,而服務端又不存在跨域,從而實現跨域訪問。

    #proxy 服務器 配置
    server {
      listen       8888;
      server_name  localhost;

      location / { 
         proxy_pass http://localhost:8080; # 除localhost:8888/api/ 外的其他請求代理到 localhost:8080 (前端自己的服務)
      }

      location /api/ {
         proxy_pass http://test.后端接口.com; # 將 localhost:8888/api/ * 請求代理到了http://test.后端接口.com; (后端接口服務器)
      }
    }

2). nginx 僅代理后端接口地址,設置為允許所有的 域請求或允許前端的域請求。實質和CORS跨域原理一樣,通過配置文件設置請求響應頭Access-Control-Allow-Origin...等字段。

    #proxy 服務器 配置
    server {
      listen       8888;
      server_name  localhost;

      location / {
          root   html;
          index  index.html index.htm;
      }

      location /api/ {  # 當請求為 localhost:8888/api/* 時,  代理轉發到 http://test.后端接口.com/api/* 
          proxy_pass   http://test.后端接口.com;  # 后端目標服務器
          add_header Access-Control-Allow-Origin http://localhost:8888;  #當前端只跨域不帶cookie時,可設置為 *
          add_header Access-Control-Allow-Credentials true;
      }
    }

4. 猜想

看到這里,也許你的心里會有疑問,既然 nginx 可以有兩種實現的思路,那么前面的 webpack 和 node.js 應該也可以做到啊,因為他們在這里都是作為代理服務器使用的啊?
恭喜你猜對了,答案是:可以的。
對於 node.js 和 webpack 的開發服務器,我們同樣可以實現,既代理靜態資源又代理后端接口的方案,簡單說:就是讓瀏覽器的所有請求都走代理服務器,根據不同的請求規則,由代理服務器去匹配對應的資源或接口

比如,下面的 node.js 方案:

const express = require('express');
const app = express();
const { createProxyMiddleware } = require('http-proxy-middleware');

const port = 8888;

app.use('/html', createProxyMiddleware({  // 當瀏覽器訪問 localhost:8888/html/ 時,匹配的是前端資源
    target: 'http://0.0.0.0:8082', // 前端資源地址
    changeOrigin: true,
    pathRewrite: {
        '^/html' : '/',     // 重寫請求
    }
}));

app.use('/api', createProxyMiddleware({ // 當瀏覽器訪問 localhost:8888/api/ 時,匹配的是接口地址
    // 代理跨域目標接口
    target: 'https://test.接口.com',
    changeOrigin: true,
    pathRewrite: {
        '^/api' : '/',     // 重寫請求
    },
    // 修改響應頭信息,實現跨域並允許帶cookie
    onProxyRes: function(proxyRes, req, res) {
        const origin = req.headers.origin || '*'
        res.header('Access-Control-Allow-Origin', origin); 
        res.header('Access-Control-Allow-Credentials', 'true');
    }
}));

app.listen(port);

5.最后

總結: 相對來說,使用 webpack 來實現跨域的配置是最簡單的、成本最低的一種解決方案,也是我平時開發中用的最多的,這里比較推薦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM