迹忆客 EN >

当前位置:主页 > 学无止境 > 网络 >

post Upload上传文件中multipart/form-data 做的那些事

作者:迹忆 最近更新:2022/11/13 浏览次数:

大家在使用form上传文件的时候都用到过 enctype=”multipart/form-data” 这个属性,那multipart/form-data 到底有什么作用呢,下面我们就来聊一聊这个话题。首先我们先看一个案例

看第一种代码

 

<form action="handle.php" method="post" >
   <input type="text" name="uname" class="uname" /><br />
   <input type="text" name="email" class="email" /><br />
   <input type="file" name="file" class="file" /><br />
   <input type="submit" name="submit" value="提交"/>
</form>

请求头信息如下

 

POST /article/handle.php HTTP/1.1
Host: www.soapstudy.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://www.soapstudy.com/article/postupload.html
Connection: keep-alive
Content-Length : 65
Content-Type: application/x-www-form-urlencoded

消息体:

 

uname=1234&email=12345&file=desktop.jpg&submit=%E6%8F%90%E4%BA%A4

看着眼熟,类似于 get方式传输地址栏中的 参数名1=参数值1&参数名2=参数值2 的形式。很明显,此种方式只是将文件名称通过post方式传输给服务器,仅有名称而无文件信息,这样是无法上传文件的。

接下来看第二类代码

 

<form action="handle.php" method="post" enctype="multipart/form-data">
   <input type="text" name="uname" class="uname" /><br />
   <input type="text" name="email" class="email" /><br />
   <input type="file" name="file" class="file" /><br />
   <input type="submit" name="submit" value="提交"/>
</form>

和第一段代码唯一不同的地方是form表单多了属性 enctype=”multipart/form-data” 接着在表单中输入同样的内容提交,请求信息如下

请求头信息

 

POST /article/handle.php HTTP/1.1
Host: www.soapstudy.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://www.soapstudy.com/article/postupload.html
Connection: keep-alive
Content-Length:529278
Content-Type:multipart/form-data;boundary=---------------------------11810260022182

(请求头信息和第一种方式不同的地方是 Content-Type, 第一种方式为application/x-www-form-urlencoded, 而此种方式为multipart/form-data; 紧跟着就是 boundary=---------------------------11810260022182——这是用来分割消息体中不同内容的,可以认为是边界,在消息体中可以看到此项应用)

消息体
(图一)

 

 

中间那乱七八糟的一大堆的东西应该就是我们的文件信息,这样服务器端收到这些信息以后,就可以将这些信息处理成相应的文件了。

通过以上案例的两种方式可以得出form表单提交数据的两种方式

1. application/x-www-form-urlencoded

2. multipart/form-data

第一种方式不能用于上传文件,只能提交文本,当然如果有file控件的话也只能提交文件名,服务器端(以PHP为例)可以通过 $_POST[]的方式接收。(可以参考 关于application/x-www-form-urlencoded 这篇文章)

第二种方式——也是我们接下来将要讨论的方式——可用于上传文件,当然服务器端处理方式不同,通过$_FILES 来接收文件信息
下面我们着重讨论multipart/form-data

(为了下文书写方便,我们将boundary=---------------------------11810260022182定义成一个变量$boundary 此变量的值为---------------------------11810260022182)

正如它的名字(form-data)所描述的一样,multipart/form-data 是用来表示表单提交的数据的,它的格式和所有的multipart MIME 数据流的格式一样。如RFC 2388描述的那样,multipart/form-data 包含很多部分,各部分之间用 --$boundary分割 其格式如下

 

--$boundary   //开始
Content-Disposition: form-data;name=”field1”
Content-Type:text/plain
Content-Transfer-Encoding:******
内容
--$boundary
Content-Disposition: form-data;name=”field2”
Content-Type:image/jpeg
内容
--$boundary-- //结束

接下来对每一项做一个大概的解释

1、--$boundary

边界是由 “--”加上$boundary(在请求头的content-type中定义的boundary=---------------------------11810260022182,见上述案例的第二种实现方式),因此消息体中的边界是比请求头中定义的多两个‘-’。对于$boundary的这个值来说,不同的应用程序(当然我们这里说的就是浏览器)产生的规则不同。

Google浏览器:

 

火狐浏览器:

 

 

但是有一点可以肯定,这个值不会和数据部分抑或是数据部分的某一段相同,当然相同的几率也是有的,不过概率非常之小,如果被我们碰上,那我们也算是相当的幸运了。

2、Content-Disposition

此项用于指定当前的呈现方式。  multipart/form-data 包含有很多部分,每一部分都包含一个Content-Disposition 头(定义在RFC 2183 )。此项的类型 为 form-data。对于name项,其值为form表单中 input的属性name的值。当然,除了类型和name这两项还可能有其它的属性,例如在案例中第二种方式的图一中可以看到第三部分还有filename项。根据传输的数据的类型的不同,Disposition 下面的内容是不同的。详细了解可以参考RFC 2183。

3、Content-Type

传输内容的类型  在multipart/form-data包含的每一项中都会有Content-Type选项,此项的默认类型为 text/plain(文本形式)。像图一中的前两部分内容是文本,因此Content-Type的类型为text/plain 由于此项为默认类型,所以有些应用程序是不显示出来的,而对于图一中的第三部分是一个图片的时候,Content-Type的类型为image/jepg。
当然此项是根据表单中的input框中的内容指定的,如果一个文件可以被作为一个正确的媒体类型,那Content-Type 的值就为此文件的类型,例如application/octet-stream、image/jpeg等。

4、Content-Transfer-encoding

当传输内容的编码方式不符合默认的编码方式的时候,此项会被用来指定相应的编码方式——可见图一中各部分数据的编码方式都符合,因此此项没有显示。

5、数据

此项就是编码以后的数据了

通过对以上几项的解释,对multipart/form-data 的格式有了一个大致的了解。当然,了解这些可能对我们当下编写只使用form表单上传文件的程序来说没有什么帮助,但是在我看来,多了解一些细节对于我们以后编写类似的程序会有很大的帮助,毕竟对于我们程序员来说要知其然,更要知其所以然。

由于本人水平有限,无法触及到更深层次的知识,本篇权当抛砖引玉,希望有高手指教,如有兴趣请在下方留言,共同讨论,共同进步

上一篇:没有了

下一篇:关于application/x-www-form-urlencoded

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Network Interfaces in Linux

发布时间:2025/04/20 浏览次数:131 分类:OPERATING SYSTEM

/etc/network/interfaces This article will look at the complete syntax explanation in Debian and its derivatives . The file /etc/network/interfaces allows you to assign static and dynamic IP addresses to interfaces, configure routing informa

Different ways to send a POST request in Vue

发布时间:2025/04/20 浏览次数:152 分类:Vue

In Vue, sending a POST request is a very common operation, which can be achieved in many ways. This article will introduce several methods of sending a POST request in Vue, and will explain it in detail with examples. Method 1: Using Vue-re

Uploading images in Angular

发布时间:2025/04/18 浏览次数:122 分类:Angular

This article describes the following: Use Angular to upload images in four different styles. Display a progress bar while images are uploading. After uploading is complete, the image upload completion message will be displayed. Uploading im

HTTP POST request in Node.js

发布时间:2025/04/17 浏览次数:131 分类:Node.js

In this article, we will learn how to use Node.js to make a post request using a third-party package. HTTP Post Request in Node.js The HTTP POST method creates or adds resources on the server. The key difference between POST and PUT request

Check if a Post exists in PHP

发布时间:2025/04/13 浏览次数:171 分类:PHP

PHP $_POST is a super global variable that can contain key-value pairs of HTML form data submitted through the post method. We will learn different ways to check $_POST if a and contains some data in this article. These methods will use iss

PHP upload image

发布时间:2025/04/13 浏览次数:62 分类:PHP

We can upload images in PHP using simple file upload operation, but first, php.ini file upload should be enabled from Files. This tutorial demonstrates how to upload images in PHP. php.ini Enable file upload from file in PHP to upload image

Terminate the PostgreSQL connection

发布时间:2025/04/11 浏览次数:200 分类:PostgreSQL

In this article, we will learn how to terminate a PostgreSQL session. Any open connections are run by background processes or tasks, PSQL which may no longer exist despite exiting the user interface or command line tool. Use ps -ef or grep

Single query to rename and change column type in PostgreSQL

发布时间:2025/04/11 浏览次数:166 分类:PostgreSQL

This article describes how to rename a column and change its type in PostgreSQL using only a single query. Renaming and changing column types in MySQL In MySQL , if you want to change the column type and rename it, you can use a simple stat

Joining columns using Select in PostgreSQL

发布时间:2025/04/11 浏览次数:176 分类:PostgreSQL

MySQL PostgreSQL is an object-relational database system, which means it can support more complex data types than its competitors . Today we will learn how to use SELECT the operator to join the columns of a table. Using operators to || joi

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便