Java结合JS实现URL编解码

 2024-02-18 05:02:49  阅读 0

通常如果某些东西需要编码,就意味着它不适合传输。 原因有多种,比如Size太大,包含私有数据等。 对于Url来说,之所以要进行编码,是因为Url中的某些字符会造成歧义。

例如Url参数字符串使用key=value对来传递参数,键值对之间用&符号分隔,如/s?q=abc& ie=utf-8。 如果你的值字符串中包含=或&,那么必然会导致接收Url的服务器出现解析错误。 因此,有歧义的&和=符号必须进行转义,即编码。

再比如,Url的编码格式使用的是ASCII码,而不是. 这意味着您不能在 URL 中包含任何非 ASCII 字符,例如中文。 否则,如果客户端浏览器和服务器浏览器支持的字符集不同,中文可能会出现问题。

URL编码的原理是用安全字符(没有特殊用途或意义的可打印字符)来表示不安全字符。

预备知识:URI的意思是统一资源标识符。 通常我们所说的 URL 只是 URI 的一种。 典型的 URL 格式如下。 下面提到的URL编码实际上应该指的是URI编码。

哪些字符需要编码

文档规定Url只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。 该文档对Url的编码和解码提出了详细的建议,指出了哪些字符需要进行编码,以免引起Url语义的改变,并对于为什么需要对这些字符进行编码提供了相应的解释。

US-ASCII 字符集中没有对应的可打印字符:Url 中只允许使用可打印字符。 US-ASCII码中的10-7F字节全部代表控制字符,这些字符不能直接出现在Url中。 同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,所以不能放在Url中。

保留字符:Url 可以分为几个组成部分,如协议、主机、路径等。一些字符(:/?#[]@)用于分隔不同的组成部分。 例如:冒号用于分隔协议和主机,/用于分隔主机和路径,? 用于分隔路径、查询参数等。还有一些字符(!$&'()*+,;=)用于分隔各个组成部分。 例如,查询参数中使用=表示键值对,&符号用于分隔查询倍数。 键值对。 当组件中的普通数据包含这些特殊字符时,需要对其进行编码。

以下字符被指定为保留字符: ! * '(); : @ & = + $ , / ? #[]

不安全字符:还有一些字符直接放入 URL 中时可能会导致解析器产生歧义。 由于多种原因,这些字符被认为是不安全的。

需要注意的是,对于Url中的合法字符,编码和不编码是等价的。 但是,对于上面提到的字符,如果不进行编码,可能会导致Url的语义不同。 因此,对于Url来说,未编码的Url中只能出现普通的英文字符和数字、特殊字符$-_.+!*'()和保留字符。 其他字符需要经过编码才能出现在 Url 中。

但由于历史原因,仍然存在一些不标准的编码实现。 例如,对于~符号,虽然文档规定波浪号符号~不需要进行URL编码,但是仍然有很多老的网关或者传输代理会对它进行编码。

如何对Url中的非法字符进行编码

url编码通常被称为百分号编码(Url,也称为-),因为它的编码方法非常简单,使用%百分号加两个字符——代表一个字节的十。 十六进制形式。 用于 URL 编码的默认字符集是 US-ASCII。 比如a在US-ASCII码中对应的字节是0x61,那么编码后得到的URL就是%61。 当我们在地址栏输入%61%62%63时,其实相当于在网上搜索abc。 又比如@符号在ASCII字符集中对应的字节是0x40,经过Url编码后得到的值为%40。

对于非ASCII字符,需要使用ASCII字符集的超集对对应的字节进行编码,然后对每个字节进行百分比编码。 对于字符,RFC文档建议使用UTF-8编码得到对应的字节,然后对每个字节进行百分比编码。 例如“中文”使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,Url编码后得到“%E4%B8%AD%E6%96%87”。

如果某个字节对应于 ASCII 字符集中的非保留字符,则该字节不需要用百分号表示。 例如“Url编码”,使用UTF-8编码得到的字节为0x55 0x72 0x6C 0xE7 0xBC 0x96 0xE7 0xA0 0x81。 由于前三个字节对应于ASCII中的非保留字符“Url”,因此这三个字节可以用非保留字符“Url”来表示。 最终的Url编码可以简化为“Url%E7%BC%96%E7%A0%81”。 当然,如果用“%55%72%6C%E7%BC%96%E7%A0%81”也是可以的。 的。

由于历史原因,有些URL编码实现并不完全遵循这个原则,下面会提到。

和 之间的区别

提供了三对函数用于对Url进行编码以获得合法的Url,它们是/、/和/。 由于解码和编码过程是可逆的,因此这里只解释编码过程。

这三个编码函数-、、-都是用来将不安全、非法的Url字符转换成合法的Url字符表示。 它们有以下区别。

安全字符不同

下面列出了这三个函数的安全字符(即函数不会对这些字符进行编码)

兼容性有所不同

该函数从1.0开始就存在,另外两个函数是在1.5中引入的。 但由于1.5已经很流行了,所以使用时其实不存在兼容性问题。

字符的编码方式不同:这三个函数对ASCII字符的编码方式是一样的,都是用百分号+两个十六进制字符来表示。 但对于字符来说,编码方式是%uxxxx,其中xxxx是4位十六进制字符,用来表示字符。 此方法已被 W3C 弃用。 但这种编码语法仍然保留在 ECMA-262 标准中。 然后使用 UTF-8 对非 ASCII 字符进行编码,然后对它们进行百分比编码。 这是 RFC 推荐的。 因此,建议尽可能使用这两个函数来代替编码。

适用于不同场合

用于对完整的 URI 进行编码,并用于对 URI 的组成部分进行编码。 从上面提到的安全字符范围表来看,我们会发现编码的字符范围大于。 上面我们提到,保留字符一般用来分隔URI的组成部分(一个URI可以被切分成多个组成部分,参考预备知识部分)或者子组成部分(比如URI中查询参数的分隔符),比如:用于分隔主机和主机,? 字符用于分隔主机和路径。 由于操作的对象是一个完整的URI,这些字符在URI中有特殊的用途,所以这些保留字符不会被编码,否则含义就会改变。

组件内部有自己的数据表示格式,但是这些数据不能包含分隔组件的保留字符,否则会造成整个URI中组件分隔的混乱。 因此,对于要使用的单个组件,需要编码更多的字符。

表单提交

当提交 Html 表单时,每个表单字段在发送之前都会进行 URL 编码。 由于历史原因,表单使用的URL编码实现不符合最新标准。 例如,用于空格的编码不是%20,而是+。 如果使用 Post 方法提交表单,我们可以在 HTTP 标头中看到一个 -Type,其值为 /x-www-form-。 大多数应用程序都可以处理Url编码的这种非标准实现,但是在客户端中,没有可以将+号解码为空格的函数,只能自己编写转换函数。 另外,对于非ASCII字符,使用的编码字符集取决于当前文档使用的字符集。例如我们添加

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

这样浏览器就会用它来渲染文档(注意,当HTML文档中没有设置这个meta标签时,浏览器会根据当前用户的喜好自动选择字符集。用户也可以强制当前使用网站使用指定的字符集。)。 提交表单时,用于URL编码的字符集是。

之前使用的时候遇到了一个很困惑的问题(为什么下面专门提到)。 当我使用它的时候,我发现它的编码结果和我想象的有很大的不同。 下面是我的示例代码:



    
        <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    
    <body>
        <script type="text/javascript">
            document.write(encodeURI("中文"));
        </script>
    

运行结果输出为%E6%B6%93%EE%85%9F%E6%9E%83。 显然这不是使用UTF-8字符集进行Url编码的结果(在网上搜索“中文”,显示的Url是%E4%B8%AD%E6%96%87)。

所以我当时很怀疑,是不是和页面编码有关,但是我发现一般情况下,如果使用Url编码,是不会得到这个结果的。 后来终于发现问题是由于页面文件存储所使用的字符集与Meta标签中指定的字符集不一致造成的。 编辑器默认使用UTF-8字符集。 换句话说,文件实际上是使用UTF-8字符集存储的。 但是,由于是在Meta标签中指定的,此时浏览器会相应地解析文档,所以自然会出现“”字符串的错误,因为“”字符串是用UTF-8编码的获取字符部分为0xE4 0xB8 0xAD 0xE6 0x96 0x87。 这6个字节被浏览器解码后,就会得到另外三个汉字“一枃”(GBK中一个汉字占两个字节)。 这三个汉字传入函数的结果是%E6%B6%93%EE%85%9F%E6%9E%83。 因此,仍然使用UTF-8,不会受到页面字符集的影响。

对于含有汉字的URL的处理,不同的浏览器有不同的表现。 例如,对于 IE,如果勾选高级设置“始终以 UTF-8 发送 Url”,则 Url 路径部分中的中文会以 UTF-8 编码发送到服务器,而查询参数将被发送到服务器。 部分使用系统默认字符集进行Url编码。 为了保证最大程度的互操作性,建议放置在Url中的所有组件显式指定Url编码的某种字符集,并且不要依赖于浏览器的默认实现。

另外,很多HTTP监控工具或者浏览器地址栏在显示Url时都会自动对Url进行解码(使用UTF-8字符集)。 这就是为什么当你在中国搜索中文时,地址栏显示“URL包含中文字符”。 但实际上发送到服务器的原始 URL 仍然是经过编码的。 您可以通过访问地址栏上的 .href 来查看这一点。 在学习Url编码和解码时,不要被这些错觉所迷惑。

下面,我们举个例子:

可以通过本网站访问在线直接网址

编码规范java_java url对象编码问题_java编码方式

通过程序实现

package com.souvc.test;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* 类名: URLEncodeTest 
* 描述: 把URL 编码或是解码
* 开发人员: souvc
* 创建时间: 2015-11-30
* 发布版本:V1.0
*/ public class URLEncodeTest { public static void main(String[] args) { String URL ="http://www.souvc.com/oauthServlet"; System.out.println(urlEncodeUTF8(URL)); System.out.println(urlEncodeGb2312(URL)); System.out.println(urlDecodeUTF8("http%3A%2F%2Fwww.souvc.com%2FoauthServlet")); System.out.println(urlDecodeGb2312("http%3A%2F%2Fwww.souvc.com%2FoauthServlet")); } /** * 方法名:urlEncodeUTF8
* 详述: URL 编码
* 开发人员:souvc
* 创建时间:2015-11-30
* @param source * @return * @throws */ public static String urlEncodeUTF8(String URL) { String result = URL; try { result = URLEncoder.encode(URL, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 方法名:urlDecodeUTF8
* 详述:URL 解码
* 开发人员:souvc
* 创建时间:2015-11-30
* @param URL * @return * @throws */ public static String urlDecodeUTF8(String URL) { String result = ""; try { result = URLDecoder.decode(URL, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 方法名:urlDecodeGb2312
* 详述:URL 解码
* 开发人员:souvc
* 创建时间:2015-11-30
* @param URL * @return * @throws */ public static String urlDecodeGb2312(String URL) { String result = ""; try { result = URLDecoder.decode(URL, "gb2312"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 方法名:urlEncodeGb2312
* 详述:URL 编码
* 开发人员:souvc
* 创建时间:2015-11-30
* @param URL * @return * @throws */ public static String urlEncodeGb2312(String URL) { String result = URL; try { result = URLEncoder.encode(URL, "gb2312"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } }

这篇关于Java结合JS实现URL编解码的文章到此结束。 希望对大家的学习有所帮助,也希望大家支持 Home。

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码