POST提交数据之---Content-Type的理解

   Content-Type是指http/https发送信息至服务器时的内容编码类型,contentType用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。

在网络请求中,常用的Content-Type有如下:
text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif,
application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml 等。

其中:text/html, text/plain, text/css, text/javascript, image/jpeg, image/png, image/gif, 都是常见的页面资源类型。

application/x-www-form-urlencoded, multipart/form-data, application/json, application/xml 这四个是ajax的请求,表单提交或上传文件的常用的资源类型。

form表单中可以定义enctype属性,该属性的含义是在发送到服务器之前应该如何对表单数据进行编码。默认的情况下,表单数据会编码为
"application/x-www-form-unlencoded".

enctype常用的属性值如下:application/x-www-form-unlencoded: 在发送前编码所有字符(默认情况下);
multipart/form-data, 不对字符编码。在使用文件上传时候,使用该值。

一:application/x-www-form-urlencoded 主要用于如下:
1.1: 最常见的POST提交数据方式。
1.2:原生form默认的提交方式(可以使用enctype指定提交数据类型)。
1.3:jquery,zepto等默认post请求提交的方式。

1. 首先来看下form表单中post默认提交方式的数据;代码如下:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
</head>
<body>
  <div id="app">
    <form action="http://www.example.com" method="POST">
      <p>username: <input type="text" name="fname" /></p>
      <p>age: <input type="text" name="age" /></p>
      <input type="submit" value="提交" />
    </form>
  </div>
</body>
</html>

如下图所示:

application/x-www-form-urlencoded 是最常用的一种请求编码方式,支持GET/POST等方法,所有数据变成键值对的形式 key1=value1&key2=value2
的形式,并且特殊字符需要转义成utf-8编号,如空格会变成 %20;

默认的提交方式是 application/x-www-form-urlencoded 编码提交数据的,在chrome的network面板下,默认的请求体是被解析的。展示成formData的形式;

如下是使用ajax的方式提交的;

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script>
</head>
<body>
  <div id="app">
    <div class="btn">发送post请求</div>
  </div>

  <script>
    var obj = {
      "name": 'CntChen',
      "info": 'Front-End',
    };
    $('.btn').click(function() {
      $.ajax({
        url: 'www.example.com',
        type: 'POST',
        dataType: 'json',
        data: obj,
        success: function(d) {
          
        }
      })
    });
  </script>
</body>
</html>

如下图所示:

如上默认提交的 contentType为 application/x-www-form-urlencoded,此时提交的数据将会格式化成:
username=111&age=2;

如果请求类型type是GET的话,那么格式化的字符串将直接拼接在url后发送到服务端; 如果请求类型是POST, 那么格式化的字符串将放在http body的Form Data中发送。

二:multipart/form-data
使用表单上传文件时,必须指定表单的 enctype属性值为 multipart/form-data. 请求体被分割成多部分,每部分使用 --boundary分割;

html代码如下:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
</head>
<body>
  <div id="app">
    <form action="http://www.example.com" method="POST" enctype="multipart/form-data">
      <p>username: <input type="text" name="fname" /></p>
      <p>age: <input type="text" name="age" /></p>
      <input type="submit" value="提交" />
    </form>
  </div>
</body>
</html>

如下图所示:

ajax formdata提交数据请看这篇文章

三:application/json
在http请求中,ContentType都是默认的值 application/x-www-form-urlencoded, 这种编码格式的特点是:name/value值对,
每组之间使用&连接,而name与value之间是使用 = 连接,比如 key=xxx&name=111&password=123456; 键值对一般的情况下是没有什么问题的,
是很简单的json形式,比如如下:

{
  a: 1,
  b: 2
}

它会解析成 a=1&b=2这样的,但是在一些复杂的情况下,比如需要传一个复杂的json对象,也就是对象嵌套数组的情况下,比如如下代码:

{
  obj: [
    {
      "name": 111,
      "password": 22
    }
  ]
}

这样复杂的对象,application/x-www-form-urlencoded这种形式传递的话, 会被解析成 obj[0]['name']=111&obj[0].['password']=2这样的。
然后再转成json形式;

{
  "obj": [
    {
      "name": 111,
      "password": 22
    }
  ]
}

对于一些复制的数据对象,对象里面再嵌套数组的话,建议使用application/json传递比较好,开发那边也会要求使用application/json。因为他们那边不使用application/json的话,使用默认的application/x-www-form-urlencoded传递的话,开发那边先要解析成如上那样的,
然后再解析成json对象,如果对于比上面更复杂的json对象的话,那么他们那边是很解析的,所以直接json对象传递的话,对于他们来说更简单。

通过json的形式将数据发送给服务器。json的形式的优点是它可以传递结构复杂的数据形式,比如对象里面嵌套数组这样的形式等。

如下代码:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script>
</head>
<body>
  <div id="app">
    <div class="btn">发送post请求</div>
  </div>

  <script>
    $('.btn').click(function() {
      $.ajax({
        url: 'http://www.example.com',
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify({a: [{b:1, a:1}]}),
        success: function(d) {
          
        }
      })
    });
  </script>
</body>
</html>

但是如上代码,在浏览器运行后,发现跨域了,我们看如下截图所示:

3.1 理解ajax跨域设置 ContentType: application/json

在使用ajax跨域请求时,如果设置Header的ContentType为 application/json,它会发两次请求,第一次先发Method为OPTIONS的请求到服务器,
这个请求会询问服务器支持那些请求方法(比如GET,POST)等。如果这个请求支持跨域的话,就会发送第二个请求,否则的话在控制台会报错,第二个请求不会请求。如下我们做个简单的demo,不跨域的如下:

如下的代码:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <script type="text/javascript" src="https://tugenhua0707.github.io/html5UploadImage/js/jquery.js"></script>
</head>
<body>
  <div id="app">
    <div class="btn">发送post请求</div>
  </div>

  <script>
    $('.btn').click(function() {
      $.ajax({
        url: 'http://localhost:8081/api.json',
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify({a: [{b:1, a:1}]}),
        success: function(d) {
          
        }
      })
    });
  </script>
</body>
</html>

如下图所示:

如上我们可以看到json格式提交的数据会显示 Request Payload;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言解析HTTP中POST格式form-data需要先理解HTTP协议和POST请求的格式。HTTP协议是一种客户端-服务器协议,用于在Web浏览器和Web服务器之间传输数据POST请求是HTTP协议中的一种请求方法,用于向服务器提交数据。 在POST请求中,数据可以采用多种格式传输,其中form-data是一种常见的格式。form-data格式将数据分为多个部分,每个部分包含一个名称和一个值,以及可选的其他属性。这些部分之间用boundary分隔符进行分隔。以下是一个示例: ``` POST /example HTTP/1.1 Host: example.com Content-Type: multipart/form-data; boundary=------------------------7d33a816d302b6 --------------------------7d33a816d302b6 Content-Disposition: form-data; name="name" John Doe --------------------------7d33a816d302b6 Content-Disposition: form-data; name="email" [email protected] --------------------------7d33a816d302b6 Content-Disposition: form-data; name="file"; filename="example.txt" Content-Type: text/plain This is an example file. --------------------------7d33a816d302b6-- ``` 在C语言中解析这种格式的POST请求,可以使用以下步骤: 1. 读取HTTP请求头部,获取Content-Type和boundary字段的值。 2. 读取HTTP请求体,按照boundary分隔符将数据分为多个部分。 3. 对于每个部分,解析Content-Disposition头部和数据值。 具体实现可以使用C语言的标准库函数进行字符串处理和文件操作。以下是一个简单的示例代码: ```c #include <stdio.h> #include <string.h> #define MAX_BUF_SIZE 1024 int main() { char boundary[MAX_BUF_SIZE]; char buf[MAX_BUF_SIZE]; char filename[MAX_BUF_SIZE]; char name[MAX_BUF_SIZE]; char value[MAX_BUF_SIZE]; FILE *fp; // 读取HTTP请求头部,获取boundary值 fgets(buf, MAX_BUF_SIZE, stdin); while (fgets(buf, MAX_BUF_SIZE, stdin)) { if (sscanf(buf, "Content-Type: multipart/form-data; boundary=%s", boundary) == 1) { break; } } // 读取HTTP请求体,按照boundary分隔符将数据分为多个部分 while (fgets(buf, MAX_BUF_SIZE, stdin)) { if (strncmp(buf, "--", 2) == 0 && strstr(buf, boundary) != NULL) { // 遇到分隔符,开始解析一个部分 filename[0] = '\0'; name[0] = '\0'; value[0] = '\0'; while (fgets(buf, MAX_BUF_SIZE, stdin)) { if (strncmp(buf, "--", 2) == 0) { // 遇到下一个分隔符,结束解析这个部分 break; } else if (strncmp(buf, "Content-Disposition: ", strlen("Content-Disposition: ")) == 0) { // 解析Content-Disposition头部 if (sscanf(buf, "Content-Disposition: form-data; name=\"%[^\"]\"; filename=\"%[^\"]\"", name, filename) == 2) { // 有文件数据 fp = fopen(filename, "wb"); if (fp == NULL) { perror("fopen"); return 1; } while (fgets(buf, MAX_BUF_SIZE, stdin)) { if (strncmp(buf, "--", 2) == 0) { break; } else { fputs(buf, fp); } } fclose(fp); } else if (sscanf(buf, "Content-Disposition: form-data; name=\"%[^\"]\"", name) == 1) { // 普通表单数据 while (fgets(buf, MAX_BUF_SIZE, stdin)) { if (strncmp(buf, "--", 2) == 0) { break; } else { strcat(value, buf); } } printf("%s: %s\n", name, value); } } } } } return 0; } ``` 这段代码可以解析上传的文件和普通表单数据,并将结果输出到标准输出。在实际应用中,可能需要根据具体的业务逻辑进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值