zoukankan      html  css  js  c++  java
  • HTTP协议中的报文格式

    按照传输过程,HTTP 报文分为请求报文和响应报文。请求报文和响应报文的结构差不多,这里只对 HTTP 请求报文做一个总结。
    HTTP 请求报文由 请求行请求头请求体(请求数据)、空行 四个部分组成(空行不知道算不算报文的一部分)。

    一、请求行

      请求行有三个组成部分:请求方法、请求 URL、HTTP 协议版本组成。这三个部分占据一行,每个部分之间用空格隔开。

      在HTTP1.0版本中定义了三种请求方法: GET, POST 和 HEAD 方法

      之后HTTP1.1版本新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

      REST设计风格对应的四种请求类型 GET(获取数据)、POST(添加数据)、PUT(更新数据)、DELETE(删除数据) 就在这八种之内

    1.GET: 请求指定的页面信息,并返回实体主体。
    2.HEAD: 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
    3.POST: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
    4.PUT: 从客户端向服务器传送的数据取代指定的资源。
    5.DELETE: 请求服务器删除指定的资源。
    6.CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
    7.OPTIONS: 允许客户端查看服务器的性能。
    8.TRACE: 回显服务器收到的请求,主要用于测试或诊断。

      GET 和 POST 的区别在于 GET 请求数据存储在请求行中,而 POST 请求数据存储在请求体(BODY) 中

            

      

    二、请求头

      请求头部通知服务器有关于客户端请求的信息,由关键字/值对组成,每行一对。

     ----------请求头几种常见可选项----------
    Host: 原始的 URL 中的主机和端口 Referer: 所指向的 Web 页的 URL Accept: 客户端可以处理的 MIME 类型 Accept-Language: 客户端的首选语言(en、en-us等) Accept-Encoding: 客户端处理的编码类型(gzip、compress等) User-Agent: 客户端自身信息 Content-Type: POST 数据的 MIME 类型 Content-Length: POST 数据的大小(KB) Connection:Keep-Alive

     

    三、请求体

       POST 方法中发送到服务的表单数据或文件,是一个键值对组合。这个与请求头中 Content-Type 和 Content-Length 密切相关。

      1、不同的提交方式,对应支持的编码类型也不一样

        HTTP协议规定 POST 提交的数据必须放在消息主体,但协议并没有规定数据必须使用什么编码。如我们常见的 form 表单提交方式和 Ajax(jQuery)提交方式

          Ⅰ:form 表单提交,由 enctype 属性值决定编码类型,enctype 属性值支持三种: application/x-www-form-urlencoded、multipart/form-data、text/plain。

          Ⅱ:Ajax(jQuery)通过 contentType 属性设定编码类型,contentType 属性支持:application/x-www-form-urlencoded、multipart/form-data、text/plain、text/xml、application/json。

      2、常见的几种编码类型介绍

        2.1、application/x-www-form-urlencoded(默认值)

          所有字符都会进行编码(多个键值对之间用 "&" 连接,空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。

      Content-Type: application/x-www-form-urlencoded;charset=utf-8
      username=admin&password=admin

        2.2、multipart/form-data

          该类型用于高效传输文件、非ASCII数据和二进制数据,用指定的分隔符 --boundary 将表单数据逐项分隔。每项数据由几个部分组成:      

          Ⅰ、内容描述信息:Content-Disposition、键名等
            例如:Content-Disposition:form-data;name="username"
            例如:Content-Disposition:form-data;name="admin";filename="admin.jpg"
          Ⅱ、内容类型(可选):Content-Type,默认值为 text/plain。
          Ⅲ、回车(一个空行):用来分隔数据具体的值和其他信息。
          Ⅳ、字段具体内容(文本或二进制)。

      Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
    
      Content-Disposition:form-data;name="username"
      Content-Type:text/plain(
                              (这里为空行,表示后面是数据)
      admin(这里是Value的值)
      --WebKitFormBoundaryrGKCBY7qhFd3TrwA
      Content-Disposition:form-data;name="admin";filename="admin.jpg"(这后面必须换行)
      Content-Type:image/jpeg(这后面必须换行)
    
      ...二进制..--
      --WebKitFormBoundaryrGKCBY7qhFd3TrwA--

      3、text/plain

          按照键值对排列表单数据key1=value1 key2=value2,不进行转义。

      4、application/json

           这种方式一般在 ajax 进行批量操作操作时用的比较多,一般会结合 JSON.stringify() 函数来用。

     附录

    HTTP请求报文结构图:

    HTTP请求报文示例:

    HTTP响应报文示例:

    测试源码

    using System;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using System.Web.Script.Serialization;
    using System.IO;
    
    namespace MvcApplication1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
    
            /// <summary>
            /// GET 方式提交
            /// </summary>
            [HttpGet]
            public String HttpGet(string key1, string key2)
            {
                return string.Format("GET 方式提交: key1={0}, key2={1}", key1, key2);
            }
    
            /// <summary>
            /// POST 方式提交,application/x-www-form-urlencoded 编码
            /// </summary>
            [HttpPost]
            public String HttpPostFormUrlencoded1(string key1, string key2)
            {
                return string.Format("POST 方式提交,application/x-www-form-urlencoded 编码: key1={0}, key2={1}", key1, key2);
            }
    
            /// <summary>
            /// POST 方式提交,application/x-www-form-urlencoded 编码
            /// </summary>
            [HttpPost]
            public String HttpPostFormUrlencoded2()
            {
                string key1 = Request["key1"];
                string key2 = Request["key2"];
                return string.Format("POST 方式提交,application/x-www-form-urlencoded 编码: key1={0}, key2={1}", key1, key2);
            }
    
            /// <summary>
            /// POST 方式提交,multipart/form-data 编码
            /// </summary>
            [HttpPost]
            public String HttpPostFormData1(string key1, string key2, HttpPostedFileBase file)
            {
                file.SaveAs(string.Format("D:\{0}", file.FileName));
                return string.Format("POST 方式提交,multipart/form-data 编码: key1={0}, key2={1},fileName={2}", key1, key2, file.FileName);
            }
    
            /// <summary>
            /// POST 方式提交,multipart/form-data 编码
            /// </summary>
            [HttpPost]
            public String HttpPostFormData2()
            {
                string key1 = Request["key1"];
                string key2 = Request["key2"];
                HttpPostedFileBase file = Request.Files["file"];
                file.SaveAs(string.Format("D:\{0}", file.FileName));
                return string.Format("POST 方式提交,multipart/form-data 编码: key1={0}, key2={1},fileName={2}", key1, key2, file.FileName);
            }
    
            public class ParamModel
            {
                public string Key1 { get; set; }
                public string Key2 { get; set; }
            }
    
            /// <summary>
            /// POST 方式提交,multipart/form-data 编码(接受Json数组)
            /// </summary>
            [HttpPost]
            public String HttpPostFormJson()
            {
                string param = Request["json"];
                JavaScriptSerializer jSerializer = new JavaScriptSerializer();
                List<ParamModel> models = jSerializer.Deserialize<List<ParamModel>>(param);
                StringBuilder sb = new StringBuilder();
                foreach (ParamModel model in models)
                {
                    sb.AppendFormat("key1={0}, key2={1}", model.Key1, model.Key2);
                }
                return sb.ToString();
            }
    
            /// <summary>
            /// POST 方式提交,application/json 编码(接受Json数组)
            /// </summary>
            [HttpPost]
            public String HttpPostApplicationJson()
            {
                //如果没有指定key,可以在 InputStream 中读取数据
                using (Stream inputStream = Request.InputStream)
                {
                    using (StreamReader sr = new StreamReader(inputStream))
                    {
                        string inputString = sr.ReadToEnd();
                        JavaScriptSerializer jSerializer = new JavaScriptSerializer();
                        List<ParamModel> models = jSerializer.Deserialize<List<ParamModel>>(inputString);
                        StringBuilder sb = new StringBuilder();
                        foreach (ParamModel model in models)
                        {
                            sb.AppendFormat("key1={0}, key2={1}", model.Key1, model.Key2);
                        }
                        return sb.ToString();
                    }
                }
            }
        }
    }
    View Code
    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
        <style type="text/css">
            form { display: inline-block; border: 1px solid #808080; padding: 10px; width: 400px; margin: 10px; }
            form > div { margin-top: 4px; }
            span { display: inline-block; width: 42px; }
            input[type=text] { width: 340px; }
            input[type=submit], input[type=button] { width: 344px; cursor: pointer; }
            textarea { width: 338px; height: 67px; }
        </style>
        <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
    </head>
    <body>
        <form method="get" action="http://localhost:38925/Home/HttpGet">
            <div>GET方式</div>
            <div>
                <span>key1:</span>
                <input type="text" name="key1" value="111" />
            </div>
            <div>
                <span>key2:</span>
                <input type="text" name="key2" value="222" />
            </div>
            <div>
                <span></span>
                <input type="submit" value="提交" />
            </div>
        </form>
        <form method="post" action="http://localhost:38925/Home/HttpPostFormUrlencoded1" enctype="application/x-www-form-urlencoded">
            <div>POST application/x-www-form-urlencoded</div>
            <div>
                <span>key1:</span>
                <input type="text" name="key1" value="111" />
            </div>
            <div>
                <span>key2:</span>
                <input type="text" name="key2" value="222" />
            </div>
            <div>
                <span></span>
                <input type="submit" value="提交" />
            </div>
        </form>
    
        <p></p>
    
        <form method="post" action="http://localhost:38925/Home/HttpPostFormData2" enctype="multipart/form-data">
            <div>POST multipart/form-data(接受键值对)</div>
            <div>
                <span>key1:</span>
                <input type="text" name="key1" value="111" />
            </div>
            <div>
                <span>key2:</span>
                <input type="text" name="key2" value="222" />
            </div>
            <div>
                <span>文件:</span>
                <input type="file" name="file" />
            </div>
            <div>
                <span></span>
                <input type="submit" value="提交" />
            </div>
        </form>
        <form method="post" action="http://localhost:38925/Home/HttpPostFormJson" enctype="multipart/form-data">
            <div>POST multipart/form-data 编码(接受Json数组)</div>
            <div>
                <span>Json:</span>
                <textarea name="json">[{"key1":"admin11","key2":"admin12"},{"key1":"admin21","key2":"admin22"},{"key1":"admin31","key2":"admin32"},{"key1":"admin41","key2":"admin42"}]</textarea>
            </div>
            <div>
                <span></span>
                <input type="submit" value="提交" />
            </div>
        </form>
    
        <p></p>
    
        <form id="ajax-test">
            <div>POST application/json 编码(接受Json数组)</div>
            <div>
                <span>key1:</span>
                <input type="text" id="key11" value="key1-1" />
                <span></span>
                <input type="text" id="key12" value="key1-2" />
                <span></span>
                <input type="text" id="key13" value="key1-3" />
            </div>
            <div>
                <span>key2:</span>
                <input type="text" id="key21" value="key2-1" />
                <span></span>
                <input type="text" id="key22" value="key2-2" />
                <span></span>
                <input type="text" id="key23" value="key2-3" />
            </div>
            <div>
                <span></span>
                <input type="button" value="提交" id="ajax-submit" />
            </div>
        </form>
        <script type="text/javascript">
            $(function () {
                $("#ajax-submit").click(function () {
                    var key11 = $("#key11").val();
                    var key12 = $("#key12").val();
                    var key13 = $("#key13").val();
                    var key21 = $("#key21").val();
                    var key22 = $("#key22").val();
                    var key23 = $("#key23").val();
                    var data = '[{"key1":"' + key11 + '","key2":"' + key21 + '"},{"key1":"' + key12 + '","key2":"' + key22 + '"},{"key1":"' + key13 + '","key2":"' + key23 + '"}]';
                    $.ajax({
                        type: "POST",
                        url: "http://localhost:38925/Home/HttpPostApplicationJson",
                        contentType: "application/json",
                        data: data,
                        success: function (msg) {
                            alert(msg);
                        }
                    });
                });
            });
        </script>
    </body>
    </html>
    View Code

  • 相关阅读:
    (1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。(2)写一函数free,将前面用new函数占用的空间释放。free(p)表示将p(地址)指向的单元以后的内存段释放。
    编一程序,输入月份号,输出该月的英文月名。例如,输人3,则输出"March" ,要求用指针数组处理
    写一函数,实现两个字符串的比较。即自己写一个strcmp函数,函数原型为int strcmp(char * p1 ,char * p2); 设p1指向字符串s1, p2指向字符串s2。要求当s1=s2时,返回值为0;若s1≠s2,返回它们二者第1个不同字符的ASCII码差值(如"BOY"与"BAD"
    输入一个字符串,内有数字和非数字字符,例如:A123x456 17960? ,302tab5876,将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a1[1].....统计共有多少个整数,并输出这些数
    输入一个字符串,内有数字和非数字字符,例如:A123x456 17960? ,302tab5876,将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a1[1].....统计共有多少个整数,并输出这些数
    有一个班4个学生,5门课程 1求第1门课程的平均分; 2找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均成绩; 3找出平均成绩在90分以上或全部课程成绩在85分以上的学生。4分别编3个函数实现以上3个要求。
    sql查询重复数据
    sql筛选查询A表中B表已经存在的数据
    智能卡7816协议
    TTL电平和CMOS电平
  • 原文地址:https://www.cnblogs.com/tracine0513/p/9583407.html
Copyright © 2011-2022 走看看