背景

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编码的更多相关文章

  1. JS中URL编码参数(UrlEncode)

    JS中URL编码参数(UrlEncode) 网上有很多文字作品写涉及在JS中呈现类似UrlEncode功能时都是自定义参数来呈现,其实JS中本身就有那样的参数.参数parameter由于用类似URL的 ...

  2. js 原生url编码

    参考:http://www.runoob.com/jsref/jsref-decodeuricomponent.html

  3. 【转】关于URL编码/javascript/js url 编码/url的三个js编码函数

    来源:http://www.cnblogs.com/huzi007/p/4174519.html 关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),e ...

  4. Node.js superagent 采集 URL 编码问题

    今天在用Node学习采集的时候遇到一个问题,如这个链接地址 http://www.meishij.net/胡萝卜  就是用浏览器的方式访问链接可以打开,但用superagent 去模拟请求,就请求不到 ...

  5. 关于URL编码/javascript/js url 编码/url的三个js编码函数

    关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),encodeURI(),encodeURIComponent() 本文为您讲述关于js(javasc ...

  6. js对url的编码和解码

    最近做公众号相关, 需要在公众号里面配菜单, 才发现菜单的链接部分是编码过的, 如这样http%3A%2F%2Fw3cschool.cn%2Fmy%20test.asp%3Fname%3Dst%C3% ...

  7. JS对URL字符串进行编码/解码分析

    一.为什么要进行js编码和解码? 只有字母和数字[0-9a-zA-Z].一些特殊符号“$-_.+!*'(),”[不包括双引号].以及某些保留字,才可以不经过编码直接用于URL. 出现的情况: 网址路径 ...

  8. JS URL编码

    JS URL编码escape() 方法: 采用ISO Latin字符集对指定的字符串进行编码.所有的空格符.标点符号.特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在 ...

  9. Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php

    Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php 1. RFC2396标准 including HTML 4.01 section  ...

随机推荐

  1. HDU1518 Square(DFS,剪枝是关键呀)

    Square Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  2. 转自虫师:性能测试的 Check List

    原文地址:http://www.cnblogs.com/jackei/archive/2006/03/24/357372.html 1. 开发人员是否提交了测试申请? 2. 测试对象是否已经明确? 3 ...

  3. [深入浅出WP8.1(Runtime)]应用实例——移动截图

    10.2应用实例——移动截图 移动截图例子是实现一个把一张图片的某个部分截取出来的功能,并且用户可以选定截取的图片区间.那个该例子会使用ManipulationDelta事件来实现对截取区间的选择.然 ...

  4. iOS上让按钮文本左对齐问题

    一,问题分析 1.在做历史记录视图的时候,由于让键盘退出后才能触发表格的 didselect 那个代理方法,也就是得点两下才触发,而表格中的按钮点一下就可以立即响应. 2.于是我就有了用按钮事件代替 ...

  5. GO语言练习:网络编程 ICMP 示例

    1.代码 2.编译及运行 1.Go语言网络编程:ICMP示例代码 icmptest.go package main import ( "fmt" "net" & ...

  6. 常见MVC框架比较

    常见MVC框架比较 运行性能上: Jsp+servlet>struts1>spring mvc>struts2+freemarker>>struts2,ognl,值栈. ...

  7. Enumerators and Enumerable

    Next week task is to learn how generic enumeration interface works, try to build a sample and write ...

  8. 360safe安全卫士防网站攻击源码

    近段时间,公司网站老被攻击,于是研究起防止攻击方法,当然无外乎就是SQL注入之类的问题,无意间发现了一个360安全卫士提供的源码,觉得挺好的,咋们暂且不说防攻击效果,至少思路是很好的,奉献给大家,大家 ...

  9. java解析xml文档(dom)

    DOM解析XML文档 读取本地的xml文件,通过DOM进行解析,DOM解析的特点就是把整个xml文件装载入内存中,形成一颗DOM树形结构,树结构是方便遍历和和操纵. DOM解析的特性就是读取xml文件 ...

  10. oracle中删除表中某字段出现重复的信息 保留其中一条

    记得以前有个同事问过我这个,说是以前面试的时候碰到的问题,下面我介绍三种方法. 首先我们在这里创建一个测试表添加相应的测试数据. create table test  (id number,name ...