前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一种上传文件的写法

一种上传文件的写法

作者头像
用户5521279
发布2019-06-02 15:57:58
7520
发布2019-06-02 15:57:58
举报
文章被收录于专栏:搜狗测试搜狗测试

在HTTP协议规范中,将http请求分为三个部分:

  • 状态行
  • 请求头
  • 请求体。

当发送HTTP请求时,需要在请求头中注明发送的方法,这些方法包括:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT,其中GET和POST是最为普遍被使用的。有关POST和GET的区别,大家可以网上查询到详细的说明,今天我们在这里主要介绍一下POST中的 multipart/form-data

使用Fiddler随机查看一条POST方法的请求包,以下图为例:

在头信息中使用Content-Length注明body内容的长度。它的Content-Type是application/x-www-form-urlencoded,这意味着消息内容会经过URL编码,而空行之后的部分便是Body,即“内容”(entity)。

在早期的HTTP Post是不支持文件上传的,编程开发带来很多问题。所以在《RFC 1867 -Form-based File Upload in HTML》中增加了用以支持文件上传的类型,即在Content-Type的类型中扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时,可以使用enctype属性控制表单的MIME编码:

  • application/x-www-form-urlencoded(默认值)
  • multipart/form-data

如果form表单在不写enctype属性时,会默认为其添加了enctype属性值,并且默认值为enctype="application/x- www-form-urlencoded"。

那么multipart/form-data请求有哪些特征呢?

代码语言:javascript
复制
1. multipart/form-data的基础方法是post
2. multipart/form-data与普通post方法的不同之处:请求头,请求体。
3. multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。
4. multipart/form-data的请求体也是一个字符串,不过和普通post的请求体不同的是它的构造方式,post是简单的name=value值连接,而multipart/form-data则是添加了分隔符等内容的构造体。

通过Fiddler截取发送的请求包内容如图:

下面通过一个python实例,展示向使用multipart/form-data方式向服务端提交信息的代码。具体的内容如下:

代码语言:javascript
复制
# coding=gbk
import urllib2;
import json;
代码语言:javascript
复制
def post_data():
    parameters = {'id': '', 'user': { 'username': 'username', 'password': 'password' }, 'query': { 'from': 'A', 'Text': 'B' }}
    jdata = json.dumps( parameters )
    post_multipart( 'http://example.sogou.com/multipart', jdata )    
代码语言:javascript
复制
def post_multipart( url , fields ):
    content_type, body = encode_multipart_formdata( "data", fields )
    req = urllib2.Request( url, body )
    req.add_header( "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 SE 2.X MetaSr 1.0)" )
    req.add_header( "Accept", "*/*" )
    req.add_header( "Accept-Language", "zh-CN,zh;q=0.8" )
    req.add_header( "Accept-Encoding", "gzip,deflate,sdch" )
    req.add_header( "Connection", "keep-alive" )
    req.add_header( "Content-Type", content_type )
    req.add_header( "User-Agent1", "SogouMSE" )
    try:
        response = urllib2.urlopen( req )
        the_page = response.read().decode( 'utf-8' )
        print the_page
        return the_page
    except urllib2.HTTPError, e:
        print e.code
        pass
    except urllib2.URLError, e:
        print str( e )
        pass
代码语言:javascript
复制
def encode_multipart_formdata( key, value ):
    BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
    CRLF = '\r\n'
    L = []
    L.append( '--' + BOUNDARY )
    L.append( 'Content-Disposition: form-data; name="%s"' % key )
    L.append( '' )
    L.append( value )    
    L.append( '--' + BOUNDARY + '--' )
    L.append( '' )
    body = CRLF.join( L )
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    return content_type, body
代码语言:javascript
复制
if __name__ == '__main__':
    post_data();
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档