zoukankan      html  css  js  c++  java
  • java学习-http中get请求的非ascii参数如何编码解码探讨

    # 背景:

    看着别人项目代码看到一个PathUtils工具类,

    里面只有一个方法,String  rebuild(String Path),将路径进行URLDecoder.decode解码,避免路径中因为中文乱码导致程序异常

    上面的方法的用处是,获取到项目配置文件的路径,通过 rebuild 方法返回解码后的路径。

    # 疑惑:

    由于我不清楚Path变量是怎么样的情况,为什么要经过rebuild方法过滤一遍

    就想测试下,如果是正常中文进行解码,解码后的字符串还是一样的吗?

    String newPath = "Keywords=湿答答";
            try {
                newPath = URLDecoder.decode(newPath, "UTF-8");
                System.out.println(newPath);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    结果中文没有发生变化。

    接着我查看的 URLDecoder的decode方法,  + 号和 % 开头的字符串才会进行解码

    note:这里的编码解码也称   %百分号编码解码

    # 深入学习:

    接着,用百度搜索的下 “urldecoder 编码和解码”

    发现url编码解码主要是应用于发送 http 的 get 请求时,对特定字符串进行编码,后台服务器会对get请求的url进行解码,以保证网络传输过程中数据的正常。

    看到一篇文章 不同浏览器中URL的编码方式

     不同浏览器对编码字符的编码方式是不同的,

    如IE浏览器可以设置编码的方式

    可以设置是否发送utf-8格式的url

    浏览器对URL编码方式不一样可能会导致我们后台获取到的数据是错误的。

    浏览器编码方式有gbk,utf-8,等等,

    假设:浏览器使用gbk的编码方式编码中文参数。我们后台服务器接收到后会进行utf-8解码,因为解码方式不一样,就导致我们获取到的参数是乱码的

    为了避免这个问题我们需要自己对get请求的参数进行url编码。

    为什么要自己主动对参数进行编码呢,需要先大概看下编码解码过程

    注意:url编码解码也称   %百分号编码解码

    编码过程:

    字母,特殊用户字符(/,:@-_.等。即斜杠,逗号,点,冒号,横线,下划线等)

    会被直接跳过,不会进行编码处理,

    其他的所有字符都要经过%xx编码处理。

    encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z

    编码方法很简单,在该字节ascii码的的16进制字符前面加% 

    如 空格字符,ascii码是32,对应16进制是'20',那么urlencode编码结果是 %20

    由于JavaScript使用的是Unicode编码,也就是utf-8编码,所以编码函数也是使用utf-8编码,

    所以js的encodeURI函数,编码中文,‘爱’  是三个字节,编码后 %e7%88%b1  ,这3个十六进制就代表,爱

    解码过程:

    解码是编码的逆向,对匹配到的百分号编码进行反向解码,字母和特殊字符也会被跳过。java中会对+号字符进行特殊处理,直接用空格替换

    上面的编码和解码有一个值得注意的地方,浏览器不会对 + 号进行编码,而tomcat或jetty服务器会将这个加号使用空格替换。

    如下面的get请求

    http://localhost:8080/api/test?aa=zhang+san&p2=18

    我们java中使用request.getParameter("aa")方法获取到的aa参数的值是zhang san

    + 号被替换成的空格

    这是一种情况,用户输入,跟我们获取到的数据不一致

    还有一种情况,服务器是以 & 符号进行分割参数的,如果我们把上面+号替换成&

    http://localhost:8080/api/test?aa=zhang&san&p2=18

    我们获取到aa的值是zhang

    服务器会认为这个get请求有三个参数,以 & 为分隔符

    分别是

    aa=zhang

    san=

    p2=18

    为了避免以上问题,我们都不应该让浏览器对参数进行编码,而是我们自己做编码

  • 相关阅读:
    Shell使用
    从一道面试题谈linux下fork的运行机制
    老了,问题定位难了,xml编码解析
    javacc
    C++概述
    Notepad++中设置Windows、Unix、Mac三种行尾换行符格式间的转换
    玩转html5(一)-----盘点html5新增的那些酷酷的input类型和属性
    Java Drp项目实战—— 环境搭建
    cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測
    电话拨号盘(带触摸振动反馈)
  • 原文地址:https://www.cnblogs.com/gne-hwz/p/10115854.html
Copyright © 2011-2022 走看看