簡體   English   中英

CORS 請求錯誤,配置了標頭和 webpack-dev-server 代理

[英]CORS error on request, with headers and webpack-dev-server proxy configured

我最近幾天一直在設計一個簡單的 ReactJS+Typescript 應用程序(與 Webpack 捆綁在一起)。 現在,我開始了后端連接部分(不是我的領域,也不是我在這種情況下的責任),我遇到了一些困難。 主要問題是瀏覽器上出現 CORS 錯誤。 這是我的設置:

    "webpack": "^4.30.0",
    "webpack-dev-server": "^3.3.1",
    "typescript": "^3.4.5",
    "react": "^16.8.6",
    "axios": "^0.18.0",
    Chrome version 74.0.3729.131 (64-bit)

沒有任何類型的建議或實驗,這是我遇到的錯誤: 在此處輸入圖像描述

我已經嘗試了幾件事來解決這個問題,但沒有一個真正解決了這個問題。 它們如下:

  1. 在我的webpack.dev.ts配置文件中,我配置了 webpack 代理屬性。 我是這樣配置的:
  devServer: {
    contentBase: path.join(__dirname, process.env.PUBLIC_PATH || '../dist'),
    compress: true,
    host: process.env.DEV_HOST || 'localhost',
    port: process.env.DEV_PORT || 8000,
    open: 'chrome',
    proxy: {
      '/api': {
        target: 'http://<ip>:8888',
        secure: false,
      },
    },
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': '*',
        'Access-Control-Allow-Methods': '*',
    },
  },

對后端的請求構建如下:

const config = {
  method: 'post',
  url: '/api/login',
  data: { password: password },
};
axios(config)
  .then(resp => console.log(resp))
  .catch(error => console.log(error));

請注意,目前, password字段只是一個占位符,不會在后端進行驗證,因此不需要Access-Control-Allow-Credentials header。

令我非常失望的是,該請求似乎沒有使用配置的代理,因為這是錯誤: 在此處輸入圖像描述

在網絡選項卡上,也沒有提及后端 IP 地址。 請注意,只有在這種情況下,請求才會顯示為POST而不是OPTIONS請求。

  1. 嘗試在我這邊(客戶端)使用 CORS 控制所需的標頭配置axios 這也沒有帶來任何解決方案。 這就是我想出的:
const config = {
  method: 'post',
  url: 'http://<ip>:8888/api/login',
  data: { password: password },
  headers: {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': '*',
    'Access-Control-Allow-Methods': '*',
  },
};
axios(config)
  .then(resp => console.log(resp))
  .catch(error => console.log(error));

出現的結果類似於沒有任何配置的結果(此處附上第一張圖片)。

  1. 最后,我為 CORS 安裝了一個 Chrome 擴展,(我想)將Access-Control-Allow-Origin: * header 附加到所有請求。 這就是事情變得有趣/奇怪的地方。 在此擴展處於活動狀態(並且未對其進行配置)的情況下,即使我禁用了所有其他先前的選項,錯誤也會發生變化:

在此處輸入圖像描述

我也嘗試過同時激活所有三個先前的選項,最后一個錯誤就是出現的。

我不確定下一步要去哪里,或者如何從這里開始。 我避免請求更改服務器 API 的標頭,但作為最后的手段,我保持該選項處於打開狀態。

我已嘗試對解釋和我想要實現的目標進行徹底的解釋,但請隨時索取更多信息。

提前致謝。

畢竟,我別無選擇,只能在收到預檢( OPTIONS )請求時用幾個標頭更新后端:

  • Access-Control-Allow-Headers ,其中包含請求在同一標頭上的任何內容;
  • Access-Control-Allow-Origin ,設置為* 由於在生產中,前端和后端都是本地的,這將僅用於我們的開發環境;
  • Access-Control-Allow-Methods ,為了方便將其設置為* 我們可以指定在我們允許的域上允許哪些方法,但我們認為這對於開發環境來說不是必需的。

設置這些標志后,我將代理配置保留在 Webpack 上,如下所示:

    proxy: {
      '/api': {
        target: 'http://<ip>:8888',
        secure: false,
      },
    },
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': '*',
        'Access-Control-Allow-Methods': '*',
    },

重新測試我們的請求,一切都很順利。 我們發現沒有辦法僅在客戶端執行此操作。

謝謝大家的評論。

從加載 Web 應用程序的同一來源公開 API 后端服務器有助於繞過 CORS 限制。 這就是 webpack 開發服務器代理派上用場的地方。 首先,確保對 API 的請求尋址代理。 如果 XMLHttpRequest 或在源代碼地址中獲取絕對 URL(相對於相對 URL),則使用指示開發模式的標志來選擇代理作為源。 例如:

fetch(isDevelopment ? '/api' : 'http://backend.server.com/api')
.then(response => processResponse(response));

其次,配置代理以針對真實后端服務器上的所需 API:

devServer: {
  proxy: {
    '/api': {
      target: 'http://backend.server.com'
    }
  }
}

從瀏覽器的角度來看,不再有跨域請求。 此配置也可能足以讓服務器正確響應(例如 Jetty 9 及其 CORS 過濾器集對我來說很好用)。 另一方面,即使是同源請求,瀏覽器也可能會發送Origin標頭。 為了防止不同后端服務器上的 CORS 問題,如果有的話,請更改Origin標頭以匹配目標 URL,如下所示:

devServer: {
  proxy: {
    '/api': {
      target: 'http://backend.server.com',
      onProxyReq: proxyReq => {
        if (proxyReq.getHeader('origin')) {
          proxyReq.setHeader('origin', 'http://backend.server.com');
        }
      }
    }
  }
}

有關更多信息,請參閱dev-server和它在后台使用的http-proxy-middleware庫的文檔。 此外,像 Wireshark 這樣的 TCP/HTTP 嗅探器非常有助於了解發送的內容以及響應發送的內容。

由於響應標頭中不存在access-control-allow-origin標頭,因此您可以在代理設置中強制使用一個:

proxy: {
  '/api': {
    target: 'http://<ip>:8888',
    secure: false,
    onProxyRes: response => {
        response.headers['access-control-allow-origin'] = 'http://localhost:8000';
    },
  },
},

這意味着所有代理響應都將具有此標頭。 這個onProxyReshttp-proxy-middleware東西,來源: https : //github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md

changeOrigin設置為true 請參閱下面的鏈接。

proxy: {
  '/api': {
     target: 'http://<ip>:8888',
     secure: false,
     changeOrigin: true,
  },
},

https://webpack.js.org/configuration/dev-server/#devserverproxy

https://github.com/chimurai/http-proxy-middleware

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM