【问题标题】:HTTP status code 405 error when adding headers to request向请求添加标头时出现 HTTP 状态代码 405 错误
【发布时间】:2018-03-31 23:18:43
【问题描述】:

当使用 Axios/http 请求设置标头时,我在向服务器发出 get 请求时遇到问题。我添加的任何标头(content-type 标头除外)都会导致相同的错误:“预检响应具有无效的 HTTP 状态代码 405。”在 Chrome、Firefox、Edge 等中都是如此。

具体来说,我需要为需要连接的服务添加 Authorization 标头以进行帐户验证。

使用 API URI 在 Postman 上运行 GET 请求工作正常,我得到了所需的响应。在浏览器中的 React 应用程序中运行它会给我 HTTP 405 错误。我在本地节点服务器上运行它,并使用http://localhost:3000 安装并启用了 Google 的 Allow-Control-Origin 扩展。

当我运行没有任何标头参数的请求时:

axios.get("https://myrequest.com/req/reqservice.svc/Login",).then(data => console.log(data)).catch(err => console.log(err))

请求工作正常。当我使用标头(任何标头,但在我的情况下是授权标头)运行它时,我收到错误:

axios.get("https://myrequest.com/req/reqservice.svc/Login", { headers: { "Authorization": "randomExample" } }).then(data => console.log(data)).catch(err => console.log(err))

那么,是什么导致了这个问题?如果是 CORS 或连接问题,我一般不会在提出请求时遇到问题吗?我一直在阅读 Stack Overflow,但没有给出解决方案的答案。我完全不知道该怎么做,而且我已经为此工作了好几天,但没有一个解决方案。任何意见将不胜感激。

【问题讨论】:

  • @tanaydin 这个问题没有解决问题。我错过了什么吗?
  • 405 - 方法不允许...您的服务器可能不允许 OPTIONS 方法 - 这是什么“Google 的 allow-control-origin 扩展”?
  • @JaromandaX 这只是一个 Chrome 浏览器插件,允许浏览器和服务器之间进行 localhost 通信,而不会在 localhost 服务器上引起 CORS 问题。

标签: javascript .net node.js http-headers axios


【解决方案1】:

这是由于 CORS。您需要为预检 (OPTIONS) 请求 (Documentation) 的 Access-Control-Allow-Headers 服务器端指定正确的值

More details about CORS in general

修改您的服务器以添加缺少的标头。根据您的问题,您至少需要添加Authorization 值。

节点 js 服务器

app.use(function (req, res, next) {
//...
res.setHeader('Access-Control-Allow-Headers', 'Authorization');

关于Access-Control-Allow-Headers

Access-Control-Allow-Headers 响应标头用于响应预检请求,以指示在实际请求期间可以使用哪些 HTTP 标头。

因此,在您的服务器端响应中,当设置Access-Control-Allow-Headers 时,您需要指定一个逗号分隔标头列表。

Access-Control-Allow-Headers: <header-name>, <header-name>, ...

您只需为 custom 标头指定它,因为默认情况下某些标头已被接受。

简单的标头,Accept,Accept-Language,Content-Language,Content-Type(但只能是应用程序/x-www-form-urlencoded,multipart/form 的解析值(忽略参数)的 MIME 类型-data 或 text/plain) 始终可用,不需要在此标题中列出。

因此,在您的情况下,如果您只指定 Content-type,它就可以工作,因为默认情况下接受 Content-Type(如上所述)

注意如果Content-type的值不是上述类型之一(例如,如果您以application/json提交授权请求),则需要将其添加到列表中(逗号分隔)

节点 js 服务器

app.use(function (req, res, next) {
//...
res.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type');

【讨论】:

  • 我严重误解了这个问题☹️
  • @MunimMunna 405 错误也可能是您所说的,但由于它似乎与内容类型一起使用,我认为它可能只是标题
  • 我已删除我的答案,因为它不能解决问题。问题是关于允许授权标头。
  • 感谢您的回答。
【解决方案2】:

如果您想启用所有路由 cors,请将以下脚本添加到您的 index.js

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});

如果您只想启用单个路由 cors,您可以像这样启用它:

router.get('/corspage', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    res.send('cors problem fixed:)');
});

如果您可以使用额外的包,您可以使用cors 包以更少的代码来完成。安装包并将以下代码添加到index.js

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

如果您想使用 cors 包启用单路由:

var express = require('express')
var cors = require('cors')
var app = express()

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

【讨论】:

    【解决方案3】:

    出现此错误是因为这是一个 CORS 调用,并且您收到了一个预检请求,您的服务器必须相应地响应该请求:

    您将从客户端获得Origin: http://blah.com 标头。

    在回复预检检查时,您应该设置几个标头:

    Access-Control-Allow-Origin: http://blah.com - 设置允许的来源 * - 用于所有来源,如果需要,则为域名

    Access-Control-Allow-Credentials: true - 设置是否允许来自该来源的 cookie。

    Access-Control-Allow-Methods: POST, GET, OPTIONS - 此来源允许的操作。

    Access-Control-Allow-Headers: Content-Type - 允许来自该来源的标头您可以在此处设置自定义标头。

    这些预检检查是 OPTIONS 调用,而不是 GET 或 POST,因此您可以轻松检测到它们并正确回答。您可能不回答 Options 调用的内容,而只设置这些强制标头,以便客户端知道此连接的 CORS 策略是什么。完成此操作后,客户端将发出实际的 GET/POST 请求,就像您在调用服务器的 ajax 中发出的一样。

    【讨论】:

      猜你喜欢
      • 2018-09-13
      • 1970-01-01
      • 2014-11-20
      • 2017-09-09
      • 1970-01-01
      • 2017-05-19
      • 2015-12-27
      • 1970-01-01
      • 2015-10-17
      相关资源
      最近更新 更多