我们经常需要用 JavaScript 获取网页上某个链接的地址(href 属性),很简单,只需要 a.getAttribute("href") 就行了。一切都很顺利,除了万恶的 IE6。
有时候,我们的链接中含有汉字,为了保证链接不会因为编码问题失效,我们先要将汉字转换为 URL 编码的形式。比如,UTF-8 编码的“汉字”将被转为“%E6%B1%89%E5%AD%97”,GBK 编码的“汉字”则是“%BA%BA%D7%D6”。这样,一个形如“http://test.com/news/cartoonlist/d14-td12月义乌最有商机的小商品-p1.html”的链接(其中的汉字为 GBK 编码)将被转为“http://test.com/news/cartoonlist/d14-td12%D4%C2%D2%E5%CE%DA%D7%EE%D3%D0%C9%CC%BB%FA%B5%C4%D0%A1%C9%CC%C6%B7-p1.html”。转换之后,在各大浏览器上访问都很正常,用 js 获取链接的 href 值也很正常,除了在 IE6 下。
我们来看一下下面的代码:
4 |
< script type = "text/javascript" >
|
6 |
alert(a.getAttribute("href"));
|
点击链接,在除 IE6 的各大浏览器下表现都和预期的一致,如下图:
但在 IE6 下,取得的 href 属性中汉字编码的部分变成了乱码:
在 IE6 下,如果要对通过 js 获取 href 属性,只要 href 值的 URL 路径中含有汉字等字符(无论这些字符是用 GBK 编码的还是 UTF-8 编码的)的 URL 编码,都将遇到这样的问题。网上搜索了一番,得知大概是由于 IE6 对编码支持的不完善造成的。另外,这个问题只在 URL 编码出现在 URL 路径而不是参数(即 ? 后面的内容)或书签(即 # 后面的内容)中才会发生。比如,下面的代码中,也有 URL 汉字编码,但这些汉字编码都在参数中,所以不会有这个问题。
4 |
< script type = "text/javascript" >
|
6 |
alert(a.getAttribute("href"));
|
鉴于 IE6 在国内还有巨大的份额,我们必须要设法解决或避免这个问题。避免这个问题的方法很简单,只要规定 URL 路径中不要出现这样的汉字编码即可(URL 参数中可以出现)。但如果 URL 路径中已经大量应用汉字编码了,有办法处理吗?网上搜索了一圈无果,看来只能自己处理了。
经过测试,注意到只有用 js 获取 href 属性的值时会有这个问题,取别的属性(即使是一个自定义属性的值)都正常。比如:
4 |
< script type = "text/javascript" >
|
6 |
alert(a.getAttribute("href") + "\n" + a.getAttribute("my-attr"));
|
可以看到,js 获取的 href 属性中有乱码,但自定义属性的值是正常的。
这就有了第一个解决办法:服务器端生成 HTML 时,给每个超链接再加一个自定义属性,值和 href 的值一样。客户端 js 要处理 href 时,读取这个自定义属性就行了。
但这个方法显然很不靠谱,因为工程太浩大了,而且这个自定义属性对于除 IE6 以外的浏览器来说都是毫无用途的。
继续探索,突然想到,这个链接元素的 outerHTML 属性中的 URL 是否正常呢?试了一下,发现 outerHTML 属性是正常的,没有乱码。于是,就有了下面的更好的解决办法:
解决方案一:
04 |
< script type = "text/javascript" >
|
06 |
alert(a.getAttribute("href")); // IE 6 下有乱码
|
10 |
(href = a.outerHTML.match(/< a [^>]*?href=['"]?(.*?)['"\s]/i)) &&
|
11 |
(href = href[1]) != a.getAttribute("href")
|
12 |
) a.setAttribute("href", href);
|
14 |
alert(a.getAttribute("href")); // IE 6 下正常
|
原理很简单,读取链接 a 的 outerHTML,用正则从中找到 href 的值,这个值就是我们期望的没有乱码的值。注意,上面的代码中我们又把提取到的 href 的值写回了 href 属性,这么做的原因是用 js 写 href 属性后,再次用 js 读取时就是刚才写入的值(即刚才提取的没有乱码的值)。
这种方法很简单直观,不过有一个缺点是要读取 outerHTML 的值。另外,@yuyu1911 也总结了另外一种解决办法,我将他的代码稍作整理后,把上面的 test 函数写成如下形式:
解决方案二:
04 |
var href = a.getAttribute( "href" );
|
09 |
var i = href.search(/[\? #]/);
|
10 |
if (i == -1) i = href.length;
|
11 |
href = escape(href.substr(0, i)).replace(
|
12 |
/(%3F|%3A|%26|%3D|%23)/g,
|
这个方法的特点是不需要额外地读取 outerHTML 属性的值,同时需要处理的正则也简单一些,我简单测试了一下,它在 IE6 下性能比上面要读取 outerHTML 的方法稍高一些。这个方法的不足是需要判断浏览器是否为 IE6,因为在其它浏览器下,上面的处理过程会将正常的 URL 编码再编码一次。另外,上面的 isIE6 函数我故意留空了,因为判断浏览器版本的方法通常在大家常用的框架或库中已经有了,这儿我就不再重复实现了。
这样,在各大主流浏览器中,我们都能顺利地用 js 取得链接的 href 值了,即使 URL 路径中有经过 URL 编码的汉字。
--------------------------------------------------
上面的内容写好后,经 @wljray 提醒,注意到在 IE 下,node.getAttribute 有一点不同,它可以有两个参数,具体见这儿。具体到这个问题,通过 getAttribute 取链接的 href 属性时,可以传两个参数,如下:
1 |
a.getAttribute( "href" , iFlags);
|
其中 iFlags 的值可以为 0、1、2、4。测试如下:
02 |
< a href = "/news/d14-td12%D4%C2%D2%E5%CE%DA%D7%EE%D3%D0%C9%CC-p1.html" onmousedown = "test(this)" target = "_self" >链接1</ a >
|
04 |
< script type = "text/javascript" >
|
06 |
var v = [0, 1, 2, 4], i, s = "", iFlags;
|
07 |
for (i = 0; i < v.length ; i ++) {
|
09 |
s += " iFlags = " + iFlags + " \nhref = '"
|
10 |
+ a.getAttribute("href", iFlags) + "'\n\n";
|
注意上面的代码中,我们的 href 写的是相对路径。测试结果如下,一图胜千言:
可以看到,iFlags 为 0 或 1 时,就是默认情况,有乱码,返回的是绝对路径;iFlags 为 2 时,没有乱码,返回相对路径;iFlags 为 4 时,没有乱码,返回绝对路径。
另外,getAttribute 的第二个参数在其它浏览器中都会被安全地忽略掉,所以,综合起来,本文开头提出来的问题的最佳解决方案如下。
最终解决方案:
2 |
return a.getAttribute( "href" , 2);
|
这样,getAttribute 在各大浏览器(包括 IE6)中就都有一致的表现了。绕了一大圈,尝试了各种方法,没想到最后最佳的解决方案居然是浏览器本来就支持的。但 IE 这个属性太不常用了,我今天还是第一次知道,再次感谢告诉我这个属性的 @wljray。:-)
分享到:
相关推荐
本主题聚焦于一个常见问题——“IE浏览器在GET请求下中文乱码的问题”。这涉及到字符编码、HTTP协议以及浏览器解析网页的方式等多个知识点,我们将详细探讨这些问题及其解决方案。 首先,我们需要理解GET请求。在...
总结以上知识点,我们介绍了获取URL的基本方法、使用JavaScript获取URL参数的方法、通过jQuery扩展方法获取URL参数、正确处理URL参数编码问题,以及随着JavaScript标准更新而导致的函数替换问题。掌握这些知识点,将...
在SWFUpload的使用过程中,无论在客户端还是服务器端都要和File Object打交道,在一个File Object中包含了以下内容: { id : string, // SWFUpload file id, used for starting or cancelling and upload ...
要使用FusionCharts Free,首先需要将包含所需JavaScript和SWF文件的库导入到项目中。这些文件通常放在"Lib"目录下,包括`FusionCharts.js`和`FusionCharts.swf`。在HTML文件中通过`<script>`标签引入JavaScript文件...
这个示例代码展示了如何使用JavaScript(JS)来获取用户本地图片的路径,并将其显示在页面上的一个图像元素中。以下是这段代码的详细解释: 首先,HTML文档的头部包含了必要的元数据和脚本引用。`<meta>`标签设置了...
在本案例中,我们需要解决一个关键的问题,即如何通过Ajax传输中文值而不会出现乱码。 在描述中提到的场景是一个用户注册流程,当用户输入用户名后,需要实时检查该用户名是否已被其他用户占用。传统的方法是提交...
在网页表单中,按下回车键时自动跳转到下一个表单元素,可以利用事件监听来实现: ```javascript // 页面内回车键跳转至下一个焦点 document.getElementById("inputField").addEventListener("keydown", function...
在现代浏览器中,通常使用`window.getSelection()`来获取用户选取的文本。示例中的`Foo()`函数展示了如何获取当前选中的文本。 这些属性和方法是JavaScript编程中的基础工具,掌握它们能帮助开发者更有效地操纵网页...
11. `document.referrer`:获取当前页面的来源URL,可用于分析用户访问路径。 12. 控制窗口状态:通过ActiveXObject实现窗口的最小化、最大化和关闭功能,但这仅适用于IE浏览器。 13. 隐藏滚动条但允许滚动:通过...
JavaScript(简称JS)是Web开发中的重要脚本语言,用于实现客户端交互和动态网页效果。在文档中,我们看到了很多关于JS操作的细节,这里将它们分门别类进行详细解释: 1. **事件处理**: - `event.srcElement.tag...
虽然官方的示例可能需要较多的修改才能适应你的项目,但这里我们提供了一个最小化的集成示例,其中包含了`jsp/demo.jsp`,这是一个可以直接运行的演示页面,可以帮助你快速理解如何在JSP中调用和使用KindEditor。...
[如何使用] 下载程序,解压上传到你的服务器路径下,data目录设置777权限。访问体验超便捷的服务吧! (data目录没有写权限会导致配置修改不能保存、不能新建用户等) [关于上传问题] 程序没有做任何限制,如果需要...
矢量层在IE下闪烁可能是由于浏览器对矢量图形的支持问题,可以通过开启矢量渲染优化(如vector renderer)解决。 在地图上添加点并保存,需要与服务器端交互,将坐标信息存储到数据库,然后通过WFS服务获取并显示。...
当使用`loadXML()`加载XML数据时,可以指定URL来获取根层级的节点数据,也可以不带参数调用,此时将使用之前通过`setXMLAutoLoading()`设定的URL。 总之,DHTMLX Tree提供了一套完整的工具集,使得开发者能够创建...
- **上传设置**:如果涉及文件上传功能,要检查`config.json`或`ewebeditor.config.js`中的上传路径和URL设置,确保服务器可以访问并处理上传请求。 2. **浏览器兼容性**: - EWebEditor主要基于IE浏览器开发,...
2)修正在带有中文目录的网站路径下使用控件会出现找不到路径的BUG! 3)修正控件上传目录初始设置不支持中文目录的BUG! 4)修正当三级或以上级别目录调用控件时图片相对路径转换不正确的BUG! 5)增加提取编辑器内容中...
FCKeditor是一款强大的开源文本编辑器,特别适合用于网页中的富文本输入,它支持多种编程语言,包括JSP。在JSP应用中,FCKeditor能够提供用户友好的界面,使得非技术人员也能轻松编辑和格式化HTML内容。FCKeditor_...
10. **获取上一页URL**:`document.referrer`属性可以获取当前页面的来源URL,常用于分析用户访问路径。 11. **窗口操作**:使用ActiveX对象,如`<object>`标签,可以执行最小化、最大化和关闭窗口的操作,但这通常...
在旧版本的IE浏览器中使用,但在现代浏览器中已被`window.getSelection()`取代。 除了上述内容,`Document`对象还有其他很多功能,例如`document.getElementsByTagName()`, `document.getElementsByName()`, `...
2)修正在带有中文目录的网站路径下使用控件会出现找不到路径的BUG! 3)修正控件上传目录初始设置不支持中文目录的BUG! 4)修正当三级或以上级别目录调用控件时图片相对路径转换不正确的BUG! 5)增加提取编辑器内容中...