javascript Node.js - Express 4.x - 方法覆盖不处理 PUT 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24019489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 02:00:26  来源:igfitidea点击:

Node.js - Express 4.x - method-override not handling PUT request

javascriptnode.jsexpressconnect

提问by flukyspore

I am attempting to have the server handle a PUT request. But to no avail. The client keeps receiving "Cannot POST /" message after submitting the form. I am using Express 4.x.

我试图让服务器处理 PUT 请求。但无济于事。提交表单后,客户端不断收到“无法 POST /”消息。 我正在使用 Express 4.x。

Note that if I change "put" to "post" in my route, the request gets handled just fine...

请注意,如果我在路线中将“放置”更改为“发布”,则请求会得到很好的处理...

How can I have my server handle the 'PUT' request?

如何让我的服务器处理“PUT”请求?

SERVER:

服务器:

var express         = require("express");
var bodyParser      = require("body-parser");
var methodOverride  = require("method-override");

var app             = express();

app.use(bodyParser());
app.use(methodOverride());


app.get("/",function(req,res){
    res.render("index.ejs");
    console.log("GET received.");
});
app.put("/",function(req,res){
    console.log("PUT received: " + req.body.userName + " - " + req.body.password);
});

app.listen(1337);
console.log("Listening on 1337.");

CLIENT

客户

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
    </head>
    <body>
        <form action="/" method="post">
            First
            <input type="text" name="first">
            Last
            <input type="text" name="last">
            <input type="hidden" name="_method" value="put">
            <button type="submit">Submit</button>
        </form>
    </body>
</html>

回答by maxcnunes

A simpler way could be override using a query value:

可以使用查询值覆盖更简单的方法:

var methodOverride = require('method-override')

// override with POST having ?_method=PUT
app.use(methodOverride('_method'))

Example call with query override using HTML :

使用 HTML 进行查询覆盖的示例调用:

<form method="POST" action="/resource?_method=PUT">
  <button type="submit">Put resource</button>
</form>

回答by Tim Cooper

As of method-override v2.0.0(release 2014-06-01), the default behaviour of the middleware does not check the POST body for a _methodfield; it only checks the X-HTTP-Method-Overrideheader.

method-override v2.0.0(release 2014-06-01) 开始,中间件的默认行为不检查 POST 正文的_method字段;它只检查X-HTTP-Method-Override标题。

In order for method-override to operate as it did in previous versions, you need to provide a custom function to methodOverride, which is detailed on the project page:

为了使method-override像以前版本一样运行,您需要向 提供一个自定义函数methodOverride在项目页面上有详细说明:

custom logic

You can implement any kind of custom logic with a function for the getter. The following implements the logic for looking in req.bodythat was in method-override1:

var bodyParser     = require('body-parser')

var connect        = require('connect')
var methodOverride = require('method-override')

app.use(bodyParser.urlencoded())
app.use(methodOverride(function(req, res){
  if (req.body && typeof req.body === 'object' && '_method' in req.body) {
    // look in urlencoded POST bodies and delete it
    var method = req.body._method
    delete req.body._method
    return method
  }
}))

自定义逻辑

您可以使用getter. 下面实现了req.bodymethod-override1 中查找的逻辑:

var bodyParser     = require('body-parser')

var connect        = require('connect')
var methodOverride = require('method-override')

app.use(bodyParser.urlencoded())
app.use(methodOverride(function(req, res){
  if (req.body && typeof req.body === 'object' && '_method' in req.body) {
    // look in urlencoded POST bodies and delete it
    var method = req.body._method
    delete req.body._method
    return method
  }
}))

回答by Suhail Gupta

We could also use a simple middleware to handle x-http-method-override

我们也可以使用一个简单的中间件来处理 x-http-method-override

     var router = express.Router();

     /**
     * Middleware that detects a HTTP method tunneled,
     * inside the header of another HTTP method. Detects
     * and routs to the method mentioned in the header.
     */

    router.use((req,resp,next)=>{
        if(req.headers['x-http-method-override']){
            req.method = req.headers['x-http-method-override'];
        }
        next();
    });

回答by Kalesh Kaladharan

I just started building my first expressproject and the following code works. Coming from Laravel, I wanted my routes to check for the presence of _methodfield and determine the appropriate route. So I created a middleware to do this.

我刚刚开始构建我的第一个express项目,以下代码有效。来自 Laravel,我希望我的路线检查_method字段的存在并确定合适的路线。所以我创建了一个中间件来做到这一点。

import { RequestHandler } from "express";

// Updates the request method if there is a 
// "_method" field present in the request query or
// request body.
const methodOverride: RequestHandler = function (req, res, next) {

    // Set the request method to the "_method" value in query
    // or the request body. Perform a validation before setting the
    // request method.
    req.method = req.query._method || req.body._method || req.method;

    // Carry forward the request to next middleware
    return next();
};

export default methodOverride;

Use this middleware before any route related middlewares. And now, my forms can look like this

在任何与路由相关的中间件之前使用此中间件。现在,我的表格看起来像这样

<form action="/" method="post">
    <input type="text" name="first">
    <input type="text" name="last">
    <input type="hidden" name="_method" value="put">
    <button type="submit">Submit</button>
</form>

The router.put('/', handler)will be executed instead of router.post('/', handler)

router.put('/', handler)将被执行,而不是router.post('/', handler)

回答by Leandro Latorre

You can choose how to override:

您可以选择如何覆盖:

// override with different headers; last one takes precedence

app.use(methodOverride('X-HTTP-Method'))          // Microsoft
app.use(methodOverride('X-HTTP-Method-Override')) // Google/GData
app.use(methodOverride('X-Method-Override'))      // IBM