浏览器增强 (Browser enhancements)

“重载 POST 有两个无争议的用途。第一种是为不支持 PUT 或 DELETE 的 Web 浏览器等客户端模拟 HTTP 的统一接口” —— RESTful Web Services, Leonard Richardson & Sam Ruby.

为了让可浏览的 API 发挥作用,REST framework 需要提供一些浏览器增强功能。

从 3.3.0 版本开始,这些都是通过 javascript 启用的,使用 ajax-form 库。

基于浏览器的 PUT、DELETE 等… (Browser based PUT, DELETE, etc…)

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

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

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

请注意,在 3.3.0 之前,这种支持是基于服务器端而不是基于 JavaScript 的。由于在请求解析中引入的微妙问题,不再支持方法重载样式 (在 Ruby on Rails 中使用)。

基于浏览器的非表单内容提交 (Browser based submission of non-form content)

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

举个栗子:

  1. <form action="/">
  2. <input data-override='content-type' value='application/json' type='hidden'/>
  3. <textarea data-override='content'>{}</textarea>
  4. <input type="submit"/>
  5. </form>

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

基于 URL 的格式后缀 (URL based format suffixes)

REST framework 可以采用 ?format=json 样式的 URL 参数,这对于确定应从视图返回哪种内容类型是一个有用的快捷方式。

使用 URL_FORMAT_OVERRIDE 设置控制此行为。

基于 HTTP 标头的方法覆盖 (HTTP header based method overriding)

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

举个栗子:

  1. METHOD_OVERRIDE_HEADER = 'HTTP_X_HTTP_METHOD_OVERRIDE'
  2. class MethodOverrideMiddleware(object):
  3. def process_view(self, request, callback, callback_args, callback_kwargs):
  4. if request.method != 'POST':
  5. return
  6. if METHOD_OVERRIDE_HEADER not in request.META:
  7. return
  8. request.method = request.META[METHOD_OVERRIDE_HEADER]

基于 URL 的接受标头 (URL based accept headers)

直到 3.3.0 版本,REST framework 包含了对 ?accept=application/json 样式 URL 参数的内置支持,这将允许重写 Accept 标头。

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

例如:

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

HTML5 不支持 PUT 和 DELETE 表单吗? (Doesn’t HTML5 support PUT and DELETE forms?)

不。它曾一度用于支持 PUTDELETE 表单,但后来从规范中删除了。目前仍在讨论添加对 PUTDELETE 的支持,以及如何支持除表单编码数据之外的内容类型。