• 30multipart/form-data和application/x-www-form-urlencoded的区别(二)urlencoded之自动deocde


    结论:

    1 对于spring boot 2.1.8 post content-type:urlencode

    可以传输中文:a=卧 室&b=2&c=3

    可以传输encode:a%3D%E5%8D%A7+%E5%AE%A4%26b%3D2%26c%3D3

    (使用java socket模拟http【重点】springboot json post bug,wireshark抓http包中代码)

        private static void springbootPostUrlEncodeUrlEncode() throws Exception {
            Socket socket = new Socket();
            socket.setTcpNoDelay(true);
            socket.connect(new InetSocketAddress("127.0.0.1", 8080));
    
            new Thread(new ReadThread(socket.getInputStream())).start();
    
            String post = "POST /proxy/testhttpsPostUrlEncode HTTP/1.1
    ";
            StringBuilder sb = new StringBuilder(post);
            sb.append("AUTH: memories
    ");
            sb.append("Cookie: AUTH=memories
    ");
            sb.append("Host: 
    ");
    
            /**
             * 无论此处是否encode,spring boot 2.1.8 都能解析报文并显示正常中文字符
             * 只是有些特殊字符&=+%注意点
             */
            String bodyUrlEncoded = "a=卧 室&b=2&c=3";
            boolean toEncodeUrl = false;
            if(toEncodeUrl) {
                bodyUrlEncoded = URLEncoder.encode(bodyUrlEncode);
                System.out.println(bodyUrlEncoded);
            }
    
            sb.append("Content-Type: application/x-www-form-urlencoded
    ");
            sb.append("Content-Length:" + bodyUrlEncoded.getBytes().length +" 
    ");
            sb.append("
    ");
    
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(sb.toString().getBytes());
            outputStream.write((bodyUrlEncoded).getBytes());
        }
    
    1、它是post的默认格式,使用js中URLencode转码方法。包括将name、value中的空格替换为加号;将非ascii字符做百分号编码;将input的name、value用‘=’连接,不同的input之间用‘&’连接。
    
    2、百分号编码什么意思呢。比如汉字‘丁’吧,他的utf8编码在十六进制下是0xE4B881,占3个字节,把它转成字符串‘E4B881’,变成了六个字节,每两个字节前加上百分号前缀,得到字符串“%E4%B8%81”,变成九个ascii字符,占九个字节(十六进制下是0x244534254238253831)。把这九个字节拼接到数据包里,这样就可以传输“非ascii字符的  utf8编码的 十六进制表示的 字符串的 百分号形式”,^_^。
    
    3、同样使用URLencode转码,这种post格式跟get的区别在于,get把转换、拼接完的字符串用‘?’直接与表单的action连接作为URL使用,所以请求体里没有数据;而post把转换、拼接后的字符串放在了请求体里,不会在浏览器的地址栏显示,因而更安全一些。

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

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

    2 从1来看,tomcat会自动decode,至于它以什么规则decode的,我不关心;只是认为,如果text有=&%+这样的字符,不要使用这个contenttype,即使encode,这些字符会被遗漏忽略

    https://blog.csdn.net/vickyway/article/details/46375971 该文认为,urlencod contenttype会,json不会

    3 spring boot get请求

    /**
    * https://www.cnblogs.com/silyvin/p/12853913.html
    * 1 连同 前面的uri一起encoce,bad request
    * 2 连同pa= pb= 一起encode,取不到参数,为null
    * 3 仅=后面urlencode,服务端正常显示xxget卧 室
    */
    String get = ("GET /proxy/testhttpsGet?") + ("pa=xx&pb=") + URLEncoder.encode("卧 室") + " HTTP/1.1 ";

    4 netty 

    /**
    * https://www.cnblogs.com/silyvin/p/12853913.html
    * 1 连同 前面的uri一起encoce,uri:bad request,但仍可以基本响应,就是uri、body遗失了
    * 2 是否连同pa= pb= 一起encode,取决于我们在netty中如何解析uri,自定义的
    * 3 uri中出现中文和空格不encode,uri:bad request,但仍可以基本响应,就是uri、body遗失了
    */
    StringBuilder sb = new StringBuilder(URLEncoder.encode(getOrPost + " /xxx?") + URLEncoder.encode("pa=") + URLEncoder.encode("卧 室") + " HTTP/1.1 ");
  • 相关阅读:
    每天一个JavaScript实例-铺货鼠标点击位置并将元素移动到该位置
    Max-Min Fairness带宽分配算法
    Centos Apache和tomcat集成配置,同一时候支持PHP和JAVA执行
    Linux硬件信息查询命令
    D3DXMatrixMultiply 函数
    垃圾回收GC:.Net自己主动内存管理 上(三)终结器
    使用python抓取CSDN关注人的全部公布的文章
    公司-科技:百度
    公司-科技:阿里巴巴
    公司-科技:腾讯
  • 原文地址:https://www.cnblogs.com/silyvin/p/12853913.html
Copyright © 2020-2023  润新知