GVKun编程网logo

FormData 和 Content-Type: multipart/form-data

15

本文将介绍FormData和Content-Type:multipart/form-data的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Aja

本文将介绍FormData 和 Content-Type: multipart/form-data的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Ajax 不支持enctype="multipart/form-data"、Ajax 提交 form ENCTYPE="multipart/form-data" 的方法、C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlenco...、c# – 使用MultipartFormDataContent生成错误的Content-Type头文件的知识。

本文目录一览:

FormData 和 Content-Type: multipart/form-data

FormData 和 Content-Type: multipart/form-data

一、FormData

现代 Web 应用中频繁使用的一项功能就是表单数据序列化,XMLHttpRequest 2 级为此定义了 FormData 类型,FormData 为序列化表单以及创建与表单格式相同的数据(通过 JS 来模拟表单键值对)提供了便利。

   let xhr = new XMLHttpRequest()

    xhr.onreadystatechange = function (e) {
      if (xhr.readyState === 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
          console.log(xhr.responseText)
        } else {
          console.log(''Opps~failed~!'')
        }
      }
    }
    xhr.open(''post'', ''https://www.easy-mock.com/mock/59b95cf3e0dc663341a8fa20/example/upload'', true)

使用 post 发送表单键值对格式的请求时,依然可以使用查询字符串格式,只是要放在请求体中,即传入send()中,介绍以下几种方法:

**方法1:**直接模仿表单提交的形式,缺点是需要手动设置请求头,还要自己序列化为查询字符串的形式传给 xhr 对象。

    xhr.setRequestHeader(''Content-Type'', ''application/x-www-form-urlencoded'')
    const queryString = ''name=wangpeng&age=24&someNumberString=19''
    xhr.send(queryString)

**方法2:**使用 FormData() 构造函数,浏览器会自动识别并添加请求头 "Content-Type: multipart/form-data",且参数依然像是表单提交时的那种键值对儿,此外 FormData() 构造函数 new 时可以直接传入 form 表单的 dom 节点。

    const params = new FormData()
    params.append(''name'', ''tom'')
    params.append(''age'', 24)
    params.append(''someNumberString'', ''18'')
    xhr.send(params)

**方法3:**使用 URLSearchParams() 构造函数传入查询字符串,返回的实例和 FormData 相似,同时浏览器也做出相同的行为。

    const params = new URLSearchParams()
    params.append(''name'', ''tom'')
    params.append(''age'', 24)
    params.append(''someNumberString'', ''18'')
    xhr.send(params)

另外,URLSearchParams() 构造函数 new 时可以直接传入查询字符串格式的参数,比如:

    const params = new URLSearchParams(''name=tom&age=24&someNumberString=19'')

可见send()方法很灵活:

xhr.send("foo=bar&lorem=ipsum"); 
// xhr.send(''string''); 
// xhr.send(new Blob()); 
// xhr.send(new Int8Array()); 
// xhr.send({ form: ''data'' }); 
// xhr.send(document);

二、multipart/form-data时的HTTP消息文本

第一行是请求行,指明了方法、URI 和 HTTP 版本号; 接着是消息头(简单起见,只有一个 Conten-Type); 然后空出一行; 接下来就是消息体,可以看到使用 multipart/form-data 时,消息体通过 boundary 来分隔多个字段,且每个字段都有自己的头部,提供了额外的信息。字段的值可能是普通的字符,也可能是二进制文件:

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

------WebKitFormBoundaryyb1zYhTI38xpQxBK
Content-Disposition: form-data; name="city_id"

1
------WebKitFormBoundaryyb1zYhTI38xpQxBK
Content-Disposition: form-data; name="company_id"

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

PNG ... content of chrome.png ...
------WebKitFormBoundaryyb1zYhTI38xpQxBK--

三、multipart/form-data定义源头

multipart/form-data最初由 《RFC 1867: Form-based File Upload in HTML》文档定义。

Since file-upload is a feature that will benefit many applications, this proposes an extension to HTML to allow information providers to express file upload requests uniformly, and a MIME compatible representation for file upload responses.

文档简介中说明文件上传作为一种常见的需求,在目前(1995年)的html中的form表单格式中还不支持,因此发明了一种兼容此需求的MIME type。

The encoding type application/x-www-form-urlencoded is inefficient for sending large quantities of binary data or text containing non-ASCII characters. Thus, a new media type,multipart/form-data, is proposed as a way of efficiently sending the values associated with a filled-out form from client to server.

文档中也写了为什么要新增一个类型,而不使用旧有的application/x-www-form-urlencoded:因为旧有类型不适合用于传输大型二进制数据或者包含非ASCII字符的数据。平常我们使用这个类型都是把表单数据使用url编码后传送给后端,二进制文件当然没办法一起编码进去了。所以multipart/form-data就诞生了,专门用于有效的传输文件。


参考: 1. 豆瓣:JavaScript高级程序设计(第3版) 2. MDN: FormData 3. MDN: XMLHttpRequest.send() 4. 为什么上传文件要使用multipart/form-data 5. 谈谈form-data请求格式

Ajax 不支持enctype=

Ajax 不支持enctype="multipart/form-data"

Ajax 不支持enctype="multipart/form-data" 所以用隐藏 iframe 来处理无刷新表单提交.

DWZ的前台的form应该写成

<form method="post" action="url"https://www.jb51.cc/tag/required/" target="_blank">required-validate" enctype="multipart/form-data" onsubmit="return iframeCallback(this,[navTabAjaxDone/dialogAjaxDone]);">

Ajax 提交 form ENCTYPE=

Ajax 提交 form ENCTYPE="multipart/form-data" 的方法

转载:通过Ajax方式上传文件,使用FormData进行Ajax请求 (http://yunzhu.iteye.com/blog/2177923 )


该方法通过 formData的方式进行处理,比较方便易懂!!

C# form表单提交enctype=

C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlenco...

1.application/x-www-form-urlencoded

GET方式,会将表单中的数据(键值对)经过urlencode编码后追加到url中。

POST方式,会将表单中的数据经过urlencode编码后放在request body 中。

2.multipart/form-data

当需要在表单内上传文件时(二进制流数据)时,就需要使用 multipart/form-data

"application/x-www-form-urlencoded",他是默认的MIME内容编码类型,一般可以用于所有的情况。但是他在传输比较大的二进制或者文本数据时效率极低。这种情况应该使用"multipart/form-data"。如上传文件或者二进制数据和非ASCII数据。

application/x-www-form-urlencoded 消息中:

......

name=ryan+ou&email=ryan@rhythmtechnology.com

......

(不同的field会用"&"符号连接;空格被替换成"+";fieldvalue间用"="联系,等等)

再看multipart/form-data 消息中:

......

-----------------------------7cd1d6371ec

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

 

ryan ou

-----------------------------7cd1d6371ec

Content-Disposition: form-data; name="email"

 

ryan@rhythmtechnology.com

-----------------------------7cd1d6371ec

Content-Disposition: form-data; name="Logo"; filename="D:\My Documents\My Pictures\Logo.jpg"

Content-Type: image/jpeg

 ......

(每个field被分成小部分,而且包含一个value"form-data""Content-Disposition"的头部;一个"name"属性对应fieldID,等等)

 

 

 

-------------------------------------------------

application/x-www-form-urlencoded

 

1、它是post的默认格式,使用jsURLencode转码方法。包括将namevalue中的空格替换为加号;将非ascii字符做百分号编码;将inputnamevalue用‘=’连接,不同的input之间用‘&’连接。

 

2、百分号编码什么意思呢。比如汉字‘丁’吧,他的utf8编码在十六进制下是0xE4B881,占3个字节,把它转成字符串‘E4B881’,变成了六个字节,每两个字节前加上百分号前缀,得到字符串“%E4%B8%81”,变成九个ascii字符,占九个字节(十六进制下是0x244534254238253831)。把这九个字节拼接到数据包里,这样就可以传输“非ascii字符的  utf8编码的 十六进制表示的 字符串的 百分号形式”,^_^

 

3、同样使用URLencode转码,这种post格式跟get的区别在于,get把转换、拼接完的字符串用‘?’直接与表单的action连接作为URL使用,所以请求体里没有数据;而post把转换、拼接后的字符串放在了请求体里,不会在浏览器的地址栏显示,因而更安全一些。

---------------------

multipart/form-data

 

1、对于一段utf8编码的字节,用application/x-www-form-urlencoded传输其中的ascii字符没有问题,但对于非ascii字符传输效率就很低了(汉字‘丁’从三字节变成了九字节),因此在传很长的字节(如文件)时应用multipart/form-data格式。smtp等协议也使用或借鉴了此格式。

 

2、此格式表面上发送了什么呢。用此格式发送一段一句话和一个文件,请求体如下

 

 

 

同时请求头里规定了Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymNhhHqUh0p0gfFa8

 

可见请求体里不同的input之间用一段叫boundary的字符串分割,每个input都有了自己一个小header,其后空行接着是数据。

 

3、此格式实际上发送了什么呢。fiddler抓包如下

 

 

 

右边明显看到了一段乱码,为什么呢,以汉字‘丁’为例,其utf8编码为0xE4B881,这三个字节会直接拼接到数据包中,即其在实际发送时只占三字节,上图右边是逐字节转为ascii字符显示的,因此会显示为三个乱码字符。

 

4、由上可见,multipart/form-data将表单中的每个input转为了一个由boundary分割的小格式,没有转码,直接将utf8字节拼接到请求体中,在本地有多少字节实际就发送多少字节,极大提高了效率,适合传输长字节。

 

"application/x-www-form-urlencoded",他是默认的MIME内容编码类型,一般可以用于所有的情况。但是他在传输比较大的二进制或者文本数据时效率极低。这种情况应该使用"multipart/form-data"。如上传文件或者二进制数据和非ASCII数据。

---------------------

版权声明:本文为CSDN博主「hula_好天气」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u013827143/article/details/86222486

c# – 使用MultipartFormDataContent生成错误的Content-Type头文件

c# – 使用MultipartFormDataContent生成错误的Content-Type头文件

我有以下代码:
private static string boundary = "----CustomBoundary" + DateTime.Now.Ticks.ToString("x");

private static async Task<string> Posttest()
{
    string servResp = "";

    using (var content = new MultipartFormDataContent(boundary))
    {
        content.Add(new StringContent("105212"),"case-id");
        content.Add(new StringContent("1/14/2014"),"dateFrom");
        content.Add(new StringContent("1/15/2014"),"dateto");

        httpclienthandler handler = new httpclienthandler();
        cookieContainer = new CookieContainer();
        handler.CookieContainer = cookieContainer;

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,"http://somewebsite.com/form");
        request.Headers.ExpectContinue = false;
        request.Content = content;

        httpClient = new HttpClient(handler);

        HttpResponseMessage response = await httpClient.SendAsync(request);
        response.EnsureSuccessstatusCode();

        servResp = await response.Content.ReadAsstringAsync();
    }

    return servResp;
}

当我运行它,我看到在fiddler的Content-Type标题:

Content-Type: multipart/form-data; boundary="----CustomBoundary8d0f01e6b3b5daf"

因为边界值是引号,服务器将忽略请求体.如果我删除引号并在fiddler Composer中运行请求,则请求被正确处理.

我尝试添加内容标题:

//request.Content.Headers.Add("Content-Type","multipart/form-data; boundary=" + boundary);
//request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data; boundary=" + boundary);

…但它没有工作,错误消息是:“无法添加值,因为标题”Content-Type“不支持多个值.和“格式的值”multipart / form-data,boundary = —- CustomBoundary8d0f024297b32d5“无效”,相应地.

如何在请求中添加适当的Content-Type标题,以便边界值不会用引号括起来?

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

解决方法

通过从MultipartFormDataContent中删除标题并重新添加它而不进行验证来解决此问题:
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type","multipart/form-data; boundary=" + boundary);

今天关于FormData 和 Content-Type: multipart/form-data的分享就到这里,希望大家有所收获,若想了解更多关于Ajax 不支持enctype="multipart/form-data"、Ajax 提交 form ENCTYPE="multipart/form-data" 的方法、C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlenco...、c# – 使用MultipartFormDataContent生成错误的Content-Type头文件等相关知识,可以在本站进行查询。

本文标签: