JS的URL编码
背景
URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号,这是网络标准:
只有字母和数字[-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字(;/?:@&=),才可以不经过编码直接用于URL。
这意味着,如果URL中有特殊字符,就必须编码后使用。但是麻烦的是,标准中未规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致"URL编码"成为了一个混乱的领域。
接下来会依次分析三种不同的情况,在每种情况中,浏览器的URL编码方法都不一样。把它们的差异解释清楚之后,我再说如何用Javascript找到一个统一的编码方法。
浏览器的URL编码方法
一、网络路径中包含特殊字符
打开Chrome浏览器,输入"http://www.cnblogs.com/yangzhinian/技术",最终在控制台中请求的URL为:http://www.cnblogs.com/yangzhinian/%E6%8A%80%E6%9C%AF
Firefox的也是同样的结果,最终我们来验证使用的是什么编码方式
decodeURIComponent("http://www.cnblogs.com/yangzhinian/%E6%8A%80%E6%9C%AF");
//结果为:http://www.cnblogs.com/yangzhinian/技术
结论1:网址路径的编码,用的是utf-8编码。
二、查询字符串包含特殊字符
在window 7操作系统下,在Chrome、Firefox浏览器中,输入"http://www.cnblogs.com/yangzhinian?wd=春节",最终在控制台中请求的URL为:
http://www.cnblogs.com/yangzhinian/?wd=%E6%98%A5%E8%8A%82
但是在window XP操作系统中,Chrome、Firefox浏览器url为:
http://www.cnblogs.com/yangzhinian/?wd=%B4%BA%BD%DA
结论2:查询字符串的编码,用的是操作系统的默认编码。
三、Get、POST方法生成的URL包含特殊字符
前面说的是直接输入网址的情况,但是更常见的情况是,在已打开的网页上,直接用Get或Post方法发出HTTP请求。根据台湾中兴大学吕瑞麟老师的试验,这时的编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。
<meta http-equiv="Content-Type" content="text/html;charset=xxxx" />
如果上面这一行最后的charset是UTF-8,则URL就以UTF-8编码;如果是GB2312,URL就以GB2312编码。
举例来说,百度是GB2312编码,Google是UTF-8编码。因此,从它们的搜索框中搜索同一个词"春节",生成的查询字符串是不一样的。
结论3:GET和POST方法的编码,用的是网页的编码。
四、Ajax调用的URL包含特殊字符
前面三种情况都是由浏览器发出HTTP请求,最后一种情况则是由Javascript生成HTTP请求,也就是Ajax调用。还是根据吕瑞麟老师的文章,在这种情况下,IE和Firefox的处理方式完全不一样。
举例来说,有这样两行代码:
url = url + "?q=" +document.myform.elements[0].value; // 假定用户在表单中提交的值是"春节"这两个字
http_request.open('GET', url, true);
那么,无论网页使用什么字符集,IE传送给服务器的总是"q=%B4%BA%BD%DA",而Firefox传送给服务器的总是"q=%E6%98%A5%E8%8A%82"。
结论4:在Ajax调用中,IE总是采用GB2312编码(操作系统的默认编码),而Firefox、Chrome总是采用utf-8编码。
Javascript编码解码方法
假定前面你都看懂了,那么此时你应该会感到很头痛。因为实在太混乱了。不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。如果程序员要把每一种结果都考虑进去,是不是太恐怖了?有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?
回答是有的,就是使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的。
Javascript语言用于编码的函数,一共有三个:escape/encodeURI/encodeURIComponent。最古老的一个就是escape(),虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它。
一、escape/unescape
escape:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:*@-_+./ 。其他所有的字符都会被转义序列替换。
unescape:是escape对应的解码方法。
实际上,escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。
如:"春节"的返回结果是%u6625%u8282,也就是说在Unicode字符集中,"春"是第6625个(十六进制)字符,"节"是第8282个(十六进制)字符。
escape("春节"); //结果:%u6625%u8282 unescape("%u6625%u8282"); //结果:春节
注意:escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心
二、encodeURI/decodeURI
encodeURI:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:-_.!~*'() 。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 方法是不会进行转义的:;/?:@&=+$,#。
decodeURI:是encodeURI对应的解码方法。如:
encodeURI("春节");//结果:%E6%98%A5%E8%8A%82 decodeURI("%E6%98%A5%E8%8A%82");//结果:春节
三、encodeURIComponent/decodeURIComponent
encodeURIComponent:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:-_.!~*'() 。其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
decodeURIComponent:是encodeURIComponent对应的解码方法。如:
encodeURIComponent('春节');//结果:%E6%98%A5%E8%8A%82 decodeURIComponent("%E6%98%A5%E8%8A%82");//结果:"春节"
JS的URL编码的更多相关文章
- JS中URL编码参数(UrlEncode)
JS中URL编码参数(UrlEncode) 网上有很多文字作品写涉及在JS中呈现类似UrlEncode功能时都是自定义参数来呈现,其实JS中本身就有那样的参数.参数parameter由于用类似URL的 ...
- js 原生url编码
参考:http://www.runoob.com/jsref/jsref-decodeuricomponent.html
- 【转】关于URL编码/javascript/js url 编码/url的三个js编码函数
来源:http://www.cnblogs.com/huzi007/p/4174519.html 关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),e ...
- Node.js superagent 采集 URL 编码问题
今天在用Node学习采集的时候遇到一个问题,如这个链接地址 http://www.meishij.net/胡萝卜 就是用浏览器的方式访问链接可以打开,但用superagent 去模拟请求,就请求不到 ...
- 关于URL编码/javascript/js url 编码/url的三个js编码函数
关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),encodeURI(),encodeURIComponent() 本文为您讲述关于js(javasc ...
- js对url的编码和解码
最近做公众号相关, 需要在公众号里面配菜单, 才发现菜单的链接部分是编码过的, 如这样http%3A%2F%2Fw3cschool.cn%2Fmy%20test.asp%3Fname%3Dst%C3% ...
- JS对URL字符串进行编码/解码分析
一.为什么要进行js编码和解码? 只有字母和数字[0-9a-zA-Z].一些特殊符号“$-_.+!*'(),”[不包括双引号].以及某些保留字,才可以不经过编码直接用于URL. 出现的情况: 网址路径 ...
- JS URL编码
JS URL编码escape() 方法: 采用ISO Latin字符集对指定的字符串进行编码.所有的空格符.标点符号.特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在 ...
- Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php
Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php 1. RFC2396标准 including HTML 4.01 section ...
随机推荐
- JDBC连接各种数据库的字符串,就是不好记
JDBC连接各种数据库的字符串大同小异,在此总结一下,备忘. oracle driverClass:oracle.jdbc.driver.OracleDriver url:jdbc:ora ...
- Android -----listView的属性大全
http://www.cnblogs.com/zhengbeibei/archive/2013/03/29/2988814.html 01 <?xml version="1.0 ...
- ACM:HDU 2199 Can you solve this equation? 解题报告 -二分、三分
Can you solve this equation? Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Su ...
- BZOJ3653: 谈笑风生
Description 设T 为一棵有根树,我们做如下的定义:• 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”.• 设a 和 b 为 T 中的两个不同节点.如 ...
- 纪念逝去的岁月——C/C++排序二叉树
1.代码 2.运行结果 3.分析 1.代码 #include <stdio.h> #include <stdlib.h> typedef struct _Node { int ...
- 抄书 Copying Books UVa 714
Copying Books 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/B 题目: Descri ...
- android中versionCode&versionName
原文来自:http://blog.csdn.net/wh_19910525/article/details/8660416 ,略有修改 一.概述 Android的版本可以在androidmainfes ...
- 关于http协议的理解
一.状态码 1.200:请求成功. 2.302:浏览器进行重定向. 3.304:资源已使用,即有缓存. 4.404:请求失败,请求的资源未在服务器上发现. 5.500:服务器端发生错误. 二.php获 ...
- 将Excel数据导入mysql数据库的几种方法
将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面 ...
- param STRING $username 要检查的用户名
检查用户名是否符合规定 两位以上的字母,数字,或者下划线,代码如下: php;auto-links:false;">/** * 检查用户名是否符合规定 * * @param STRIN ...