浏览器增强功能

“重载 POST 有两种无争议的用途。第一个是模拟 HTTP 的统一界面,适用于不支持 PUT 或 DELETE 的客户端,例如 Web 浏览器”

RESTful Web 服务,Leonard Richardson 和 Sam Ruby。

为了让可浏览 API 正常运行,REST 框架需要提供一些浏览器增强功能。

从 3.3.0 版本开始,这些功能使用 javascript 启用,并使用 ajax-form 库。

基于浏览器的 PUT、DELETE 等...

AJAX 表单库 支持基于浏览器的 HTML 表单上的PUTDELETE 和其他方法。

在包含库后,在表单上使用 data-method 属性,如下所示

<form action="/" data-method="PUT">
    <input name='foo'/>
    ...
</form>

请注意,在 3.3.0 之前,此支持是基于服务器端而不是基于 javascript 的。方法重载样式(如 Ruby on Rails 中所用)不再受支持,因为它在请求解析中引入了细微的问题。

基于浏览器的非表单内容提交

AJAX 表单库 支持基于浏览器的提交 JSON 等内容类型,使用具有 data-override='content-type'data-override='content' 属性的表单字段。

例如

    <form action="/">
        <input data-override='content-type' value='application/json' type='hidden'/>
        <textarea data-override='content'>{}</textarea>
        <input type="submit"/>
    </form>

请注意,在 3.3.0 之前,此支持是基于服务器端而不是基于 javascript 的。

基于 URL 的格式后缀

REST 框架可以采用 ?format=json 样式的 URL 参数,这可以作为确定应该从视图返回哪种内容类型的有用快捷方式。

此行为使用 URL_FORMAT_OVERRIDE 设置进行控制。

基于 HTTP 标头的覆盖方法

在 3.3.0 版本之前,支持半扩展标头 X-HTTP-Method-Override 来覆盖请求方法。此行为不再在核心,但可以在需要时使用中间件添加。

例如

METHOD_OVERRIDE_HEADER = 'HTTP_X_HTTP_METHOD_OVERRIDE'

class MethodOverrideMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.method == 'POST' and METHOD_OVERRIDE_HEADER in request.META:
            request.method = request.META[METHOD_OVERRIDE_HEADER]
        return self.get_response(request)

基于 URL 的接受标头

在 3.3.0 版本之前,REST 框架包含对 ?accept=application/json 样式的 URL 参数的内置支持,这将允许覆盖 Accept 标头。

自内容协商 API 引入以来,此行为不再包含在核心,但可以在需要时使用自定义内容协商类添加。

例如

class AcceptQueryParamOverride()
    def get_accept_list(self, request):
       header = request.META.get('HTTP_ACCEPT', '*/*')
       header = request.query_params.get('_accept', header)
       return [token.strip() for token in header.split(',')]

HTML5 不支持 PUT 和 DELETE 表单吗?

否。曾经打算支持 PUTDELETE 表单,但后来 从规范中删除。关于添加对 PUTDELETE 的支持以及如何支持除表单编码数据之外的其他内容类型,仍然存在 持续讨论