方法重写中间件
让你在客户端不支持的地方使用诸如 PUT 或 DELETE 的 HTTP 动词。
🌐 Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn’t support it.
安装
🌐 Install
这是一个可以通过npm注册表获取的Node.js模块。安装可以使用npm install命令完成:
🌐 This is a Node.js module available through the
npm registry. Installation is done using the
npm install command:
npm install method-overrideyarn add method-overridepnpm add method-overridebun add method-overrideNote
method-override 不包含其自身的 TypeScript 类型定义。如果你使用 TypeScript,还需要作为开发依赖从 DefinitelyTyped 安装社区维护的类型:
npm install --save-dev @types/method-overrideyarn add --dev @types/method-overridepnpm add --save-dev @types/method-overridebun add --dev @types/method-overrideAPI
注意 非常重要的是,本模块必须在任何需要知道请求方法的模块之前使用(例如,必须在 csurf 模块之前使用)。
methodOverride(getter, options)
创建一个新的中间件函数,用于用新值覆盖 req.method 属性。该值将从提供的 getter 中提取。
🌐 Create a new middleware function to override the req.method property with a new
value. This value will be pulled from the provided getter.
getter- 用于查找请求的重写请求方法的 getter。(默认值:X-HTTP-Method-Override)options.methods- 原始请求必须采用的允许方法,以检查方法覆盖值。(默认值:['POST'])
如果找到的方法由 node.js 核心支持,那么 req.method 将被设置为该值,就好像它本来就是该值一样。之前的 req.method 值将存储在 req.originalMethod 中。
🌐 If the found method is supported by node.js core, then req.method will be set to
this value, as if it has originally been that value. The previous req.method
value will be stored in req.originalMethod.
getter
这是从请求中获取覆盖值的方法。如果提供了一个函数,req 作为第一个参数传入,res 作为第二个参数传入,并且预期返回该方法。如果提供的是字符串,则使用该字符串根据以下规则查找方法:
🌐 This is the method of getting the override value from the request. If a function is provided,
the req is passed as the first argument, the res as the second argument and the method is
expected to be returned. If a string is provided, the string is used to look up the method
with the following rules:
- 如果字符串以
X-开头,则将其视为头的名称,并使用该头进行方法覆盖。如果请求包含相同的头多次,则使用第一次出现的头。 - 所有其他字符串都被视为 URL 查询字符串中的键。
options.methods
这允许指定请求必须使用哪些方法来检查方法覆盖值。默认情况下仅限 POST 方法,这是覆盖值应到达的唯一方法。这里可以指定更多方法,但可能引入安全问题,并在请求通过缓存时导致奇怪的行为。该值是一个以大写表示的方法数组。可以指定 null 以允许所有方法。
🌐 This allows the specification of what methods(s) the request MUST be in in order to check for
the method override value. This defaults to only POST methods, which is the only method the
override should arrive in. More methods may be specified here, but it may introduce security
issues and cause weird behavior when requests travel through caches. This value is an array
of methods in upper-case. null can be specified to allow all methods.
例子
🌐 Examples
使用头文件覆盖
🌐 override using a header
要使用头来覆盖方法,请将头名称作为字符串参数传递给 methodOverride 函数。然后要进行调用,请向 URL 发送一个 POST 请求,并将被覆盖的方法作为该头的值。通常在不支持你尝试使用的方法的实现中,会将这种使用头的方式与 XMLHttpRequest 一起使用。
🌐 To use a header to override the method, specify the header name
as a string argument to the methodOverride function. To then make
the call, send a POST request to a URL with the overridden method
as the value of that header. This method of using a header would
typically be used in conjunction with XMLHttpRequest on implementations
that do not support the method you are trying to use.
const express = require('express');const methodOverride = require('method-override');const app = express();
// override with the X-HTTP-Method-Override header in the requestapp.use(methodOverride('X-HTTP-Method-Override'));使用 XMLHttpRequest 的带有头部覆盖的示例调用:
🌐 Example call with header override using XMLHttpRequest:
const xhr = new XMLHttpRequest();xhr.onload = onload;xhr.open('post', '/resource', true);xhr.setRequestHeader('X-HTTP-Method-Override', 'DELETE');xhr.send();
function onload() { alert('got response: ' + this.responseText);}使用查询值覆盖
🌐 override using a query value
要使用查询字符串值来覆盖方法,请将查询字符串键作为字符串参数传递给 methodOverride 函数。然后,要进行调用,请向包含该查询字符串键值为被覆盖方法的 URL 发送 POST 请求。这种使用查询值的方法通常与普通 HTML <form> 元素结合使用,以在尝试支持旧版浏览器的同时仍使用较新的方法。
🌐 To use a query string value to override the method, specify the query
string key as a string argument to the methodOverride function. To
then make the call, send a POST request to a URL with the overridden
method as the value of that query string key. This method of using a
query value would typically be used in conjunction with plain HTML
<form> elements when trying to support legacy browsers but still use
newer methods.
const express = require('express');const methodOverride = require('method-override');const app = express();
// override with POST having ?_method=DELETEapp.use(methodOverride('_method'));使用 HTML <form> 的查询覆盖示例调用:
🌐 Example call with query override using HTML <form>:
<form method="POST" action="/resource?_method=DELETE"> <button type="submit">Delete resource</button></form>多格式支持
🌐 multiple format support
const express = require('express');const methodOverride = require('method-override');const app = express();
// override with different headers; last one takes precedenceapp.use(methodOverride('X-HTTP-Method')); // Microsoftapp.use(methodOverride('X-HTTP-Method-Override')); // Google/GDataapp.use(methodOverride('X-Method-Override')); // IBM自定义逻辑
🌐 custom logic
你可以为 getter 使用函数实现任何类型的自定义逻辑。以下实现了在 method-override@1 中寻找 req.body 的逻辑:
🌐 You can implement any kind of custom logic with a function for the getter. The following
implements the logic for looking in req.body that was in method-override@1:
const bodyParser = require('body-parser');const express = require('express');const methodOverride = require('method-override');const app = express();
// NOTE: when using req.body, you must fully parse the request body// before you call methodOverride() in your middleware stack,// otherwise req.body will not be populated.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 const method = req.body._method; delete req.body._method; return method; } }));使用 HTML <form> 的查询覆盖示例调用:
🌐 Example call with query override using HTML <form>:
{/* enctype must be set to the type you will parse before methodOverride() */}<form method="POST" action="/resource" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="_method" value="DELETE" /> <button type="submit">Delete resource</button></form>许可证
🌐 License