zoukankan      html  css  js  c++  java
  • form 提交数据编码梳理

    之前对form单提交的操作一直都是迷迷糊糊,知道怎么用,但是随着ajax2的出现,我们有更多的方式操作form表单提交,但是底层的原理我们要好好的做个梳理。

    常见的form提交有post和get这两种形式,他们对各自的编码都有不同的理解,post适合大量数据的提交,语义上改变了数据状态,get是一种获取获取数据的一种形式,两者在编码上是有不同的实现。

    关于编码的 form 标签的属性

    • accept-charset:可以指定form编码形式
    • enctype: 规定在发送表单数据之前如何对其进行编码。有三种设置类型
      • 默认为application/x-www-form-urlencoded:发送前编码所有字符
      • multipart/form-data:不对字符编码,包含文件上传控件的表单时,必须使用该值
      • text/plain:空格转换为 "+" 加号,但不对特殊字符编码。
    • method:规定用于发送 form-data 的 HTTP 方法。有 post 和 get

    method

    浏览器使用 method 属性设置的方法将表单中的数据传送给服务器进行处理。共有两种方法:POST 方法和 GET 方法。

    如果采用 POST 方法,浏览器将会按照下面两步来发送数据。首先,浏览器将与 action 属性中指定的表单处理服务器建立联系,一旦建立连接之后,浏览器就会按分段传输的方法将数据发送给服务器。

    在服务器端,一旦 POST 样式的应用程序开始执行时,就应该从一个标志位置读取参数,而一旦读到参数,在应用程序能够使用这些表单值以前,必须对这些参数进行解码。用户特定的服务器会明确指定应用程序应该如何接受这些参数。

    另一种情况是采用 GET 方法,这时浏览器会与表单处理服务器建立连接,然后直接在一个传输步骤中发送所有的表单数据:浏览器会将数据直接附在表单的 action URL 之后。这两者之间用问号进行分隔。

    accept-charset

    默认的,无论表单提交的method是post 还是 get,都会默认使用页面的编码进行数据的编码,但是一旦指定了这个参数,那么他就会运用你约定的编码方式来编码你的数据。

    post提交

    这里我们使用编码为GBK的页面做提交

    <form action="/example/html5/demo_form.asp" method="post">
      name: <input type="text" name="fname" /><br />
      <input type="submit" value="提交" />
    </form>
    

    提交后为http的内容为

    fname=%BA%C3
    

    如果指定 accept-charset 为 UTF-8

    <form action="/example/html5/demo_form.asp" method="post" accept-charset="UTF-8">
      name: <input type="text" name="fname" /><br />
      <input type="submit" value="提交" />
    </form>
    

    提交的内容为

    fname=%E5%A5%BD
    

    get 提交方式

    同样适用GBK页面编码提交数据

    <form action="/example/html5/demo_form.asp" method="get">
      name: <input type="text" name="fname" /><br />
      <input type="submit" value="提交" />
    </form>
    

    由于是get形式提交,参数会在请求的url上展示

    example/html5/demo_form.asp?fname=%E5%A5%BD
    

    如果指定 accept-charset 为 UTF-8

    <form action="/example/html5/demo_form.asp" method="get" accept-charset="UTF-8">
      name: <input type="text" name="fname" /><br />
      <input type="submit" value="提交" />
    </form>
    

    在提交的url后面的参数编码变为了

    example/html5/demo_form.asp?fname=%E5%A5%BD
    

    当然你可以在普通的文本提交里的form表单属性里加上 enctype=application/x-www-form-urlencoded ,表示要对所有的表单字段做编码。

    enctype="multipart/form-data"

    在用表单做文件提交时,我们必须使用这个属性标示浏览器要对编码,而且你的提交方式必须post。否则你的那文件

    比如我们使用get方法来上传文件

    <form 
      action="/example/html5/demo_form.asp" 
      method="get"
      accept-charset="UTF-8"
      enctype="multipart/form-data">
      name: <input type="text" name="fname" />
    	<input type="file" name="pic" />
      	<input type="submit" value="提交" />
    </form>
    

    提交后数据由url querystring 传入:

    /example/html5/demo_form.asp?fname=asdf&pic=FullSizeRender.jpg
    

    可以看到数据没了

    当我们使用 POST 方法提交数据后

    <form 
      action="/example/html5/demo_form.asp" 
      method="post"
      accept-charset="UTF-8"
      enctype="multipart/form-data">
      name: <input type="text" name="fname" />
    	<input type="file" name="pic" />
     	<input type="submit" value="提交" />
    </form>
    

    可以看到请求体的内容为

    ------WebKitFormBoundarypbYSrhCXKEdYIDbR
    Content-Disposition: form-data; name="fname"
    
    好
    ------WebKitFormBoundarypbYSrhCXKEdYIDbR
    Content-Disposition: form-data; name="pic"; filename="FullSizeRender.jpg"
    Content-Type: image/jpeg
    
    
    ------WebKitFormBoundarypbYSrhCXKEdYIDbR--
    

    HTML5 FormData

    进入HTML5 时代我们可以使用 ajax2 + FormData 来上传二进制流。注意请不要设置 xhr 的 contentType, 因为你使用了 form-data 形式上传数据,应该又浏览器来决定:FormBoundary的内容。

    var formData = new FormData();
    
    formData.append("username", "好");
    formData.append("accountnum", 123456); // 数字 123456 会被立即转换成字符串 "123456"
    
    var request = new XMLHttpRequest();
    request.open("POST", "http://foo.com/submitform.php");
    request.send(formData);
    

    在请求里可以看到

    ------WebKitFormBoundary0SD0cBR9xNMTPnAf
    Content-Disposition: form-data; name="username"
    
    好
    ------WebKitFormBoundary0SD0cBR9xNMTPnAf
    Content-Disposition: form-data; name="accountnum"
    
    123456
    ------WebKitFormBoundary0SD0cBR9xNMTPnAf--
    
  • 相关阅读:
    第5章 JDBC/ODBC服务器
    第4章 SparkSQL数据源
    第3章 SparkSQL解析
    第2章 执行SparkSQL查询
    第1章 Spark SQL概述
    Ubutun重启网卡
    Java面试通关要点汇总整理
    40道Java基础常见面试题及详细答案
    ListView
    数据库表及字段命名规范
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/6885199.html
Copyright © 2011-2022 走看看