将标头添加到请求时,HTTP状态代码405出错

时间:2018-03-31 23:18:44

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

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

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

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

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

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而没有回答给我解决方案。我完全迷失了该做什么,而且我已经在没有一个解决方案的情况下工作了好几天。任何意见都会非常感激。

3 个答案:

答案 0 :(得分:8)

归功于CORS。您需要为预检(OPTIONS)请求(DocumentationAccess-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响应标头用于响应预检请求,以指示在实际请求期间可以使用哪些HTTP标头。

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

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

您只需为自定义标头指定它,因为默认情况下已接受一些标头。

  

简单标题,接受,接受语言,内容语言,内容类型(但只有其应用程序/ 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');

答案 1 :(得分:2)

如果您想要启用所有路线,请将以下脚本添加到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();
});

如果您只想启用单个路由器,则可以启用它:

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'})
})

答案 2 :(得分:0)

发生此错误是因为这是一个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,因此您可以轻松检测并正确回答。您可能无法回答选项调用的内容,但只设置这些必需的标头,以便客户端知道此连接的CORS策略是什么。完成此操作后,客户端将发出实际的GET / POST请求,因为您已在调用服务器的ajax中发出它。