Django文件上传实战:Form、Ajax与ContentType详解

小满
小满
发布时间:2026-10-13 | 5人浏览过
原创

本文深入解析Django中文件上传的多种实现方式,涵盖原生Form表单与Ajax异步提交。重点讲解application/x-www-form-urlencoded、multipart/form-data及application/json三种Content-Type的区别与应用场景,并提供基于jQuery的Ajax上传代码示例及后端视图处理逻辑,帮助开发者掌握Django文件处理的核心技术。

近期状态有所波动,如今已调整完毕,让我们继续追寻技术的梦想。

本文将补充介绍几种常见的文件上传实现方案。

首先,我们需要补充一个关键的前端知识点。

一、请求头ContentType详解:

ContentType用于指定请求体的编码类型,常见的类型主要有三种。

1、application/x-www-form-urlencoded

这是最常见的POST数据提交方式。当浏览器的原生<form>表单未设置enctype属性时,默认即以此方式提交数据。其请求格式大致如下(省略无关请求头):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=duoduo&age=22

2、multipart/form-data

这是另一种常见的POST数据提交方式。在使用表单上传文件时,必须将<form>表单的enctype属性设置为multipart/form-data。

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="user"

duoduo
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

该示例相对复杂。首先生成一个boundary用于分割不同字段,为避免与正文内容重复,boundary通常较长且复杂。Content-Type中指明了数据以multipart/form-data编码,并指定了本次请求的boundary内容。消息主体按字段数量分为多个结构相似的部分,每部分以--boundary开始,紧接着是内容描述信息,随后是回车符,最后是字段具体内容(文本或二进制)。若传输文件,还需包含文件名和文件类型信息。消息主体最后以--boundary--标示结束。关于multipart/form-data的详细定义,请参考rfc1867标准。

这种方式通常用于上传文件,各大服务端语言均对其有良好支持。

上述两种POST数据方式均为浏览器原生支持,且现阶段标准中原生<form>表单仅支持这两种方式(通过<form>元素的enctype属性指定,默认为application/x-www-form-urlencoded。实际上enctype还支持text/plain,但使用频率极低)。

随着越来越多的Web站点,尤其是WebApp,全面采用Ajax进行数据交互,我们可以定义新的数据提交方式,从而为开发带来更多便利。

3、application/json

application/json作为响应头大家可能并不陌生。实际上,现在越来越多的人将其作为请求头,用于告知服务端消息主体是序列化后的JSON字符串。得益于JSON规范的流行,除低版本IE外,各大浏览器均原生支持JSON.stringify,服务端语言也提供了处理JSON的函数,使用JSON几乎不会遇到障碍。

JSON格式支持比键值对更为复杂的数据结构,这一点颇具价值。记得几年前开发项目时,需要提交的数据层次非常深,我便将数据JSON序列化后提交。当时我将JSON字符串作为val,仍置于键值对中,以x-www-form-urlencoded方式提交。

二、基于Form表单的文件上传

模块部分

<form action="" method="post" enctype="multipart/form-data">
   用户名 <input type="text" name="user">
   头像 <input type="file" name="avatar">
  <input type="submit">
</form>

视图部分

def index(request):
  print(request.body)  # 原始的请求体数据
  print(request.GET)  # GET请求数据
  print(request.POST)  # POST请求数据
  print(request.FILES) # 上传的文件数据


  return render(request,"index.html")

三、基于Ajax的文件上传

模块

<form>
   用户名 <input type="text" id="user">
   头像 <input type="file" id="avatar">
   <input type="button" id="ajax-submit" value="ajax-submit">
</form>

<script>

  $("#ajax-submit").click(function(){
    var formdata=new FormData();
    formdata.append("user",$("#user").val());
    formdata.append("avatar_img",$("#avatar")[0].files[0]);
    $.ajax({

      url:"",
      type:"post",
      data:formdata,
      processData: false ,  // 不处理数据
      contentType: false,  // 不设置内容类型

      success:function(data){
        console.log(data)
      }
    })

  })

</script>

视图

def index(request):

  if request.is_ajax():

    print(request.body)  # 原始的请求体数据
    print(request.GET)  # GET请求数据
    print(request.POST)  # POST请求数据
    print(request.FILES) # 上传的文件数据

    return HttpResponse("ok")


  return render(request,"index.html")

检查浏览器的请求头:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaWl9k5ZMiTAzx3FT

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表