浏览器增强功能
“重载 POST 有两种无争议的用途。第一个是模拟 HTTP 的统一界面,适用于不支持 PUT 或 DELETE 的客户端,例如 Web 浏览器”
— RESTful Web 服务,Leonard Richardson 和 Sam Ruby。
为了让可浏览 API 正常运行,REST 框架需要提供一些浏览器增强功能。
从 3.3.0 版本开始,这些功能使用 javascript 启用,并使用 ajax-form 库。
基于浏览器的 PUT、DELETE 等...
AJAX 表单库 支持基于浏览器的 HTML 表单上的PUT
、DELETE
和其他方法。
在包含库后,在表单上使用 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 表单吗?
否。曾经打算支持 PUT
和 DELETE
表单,但后来 从规范中删除。关于添加对 PUT
和 DELETE
的支持以及如何支持除表单编码数据之外的其他内容类型,仍然存在 持续讨论。