`
snake_hand
  • 浏览: 625011 次
社区版块
存档分类
最新评论

由莫名其妙的错误开始

 
阅读更多

本来没准备今天发博客的,在一个前端群中,一位老大哥风自由提出了一个简单却很奇特的问题:

有一个字符串是这样的:var s = '<html lang="en" class="js no-touch discourse-no-touch">'+ '<head><meta name="csrf-token" content="Oul7WqVh4FBVse2yGeY8ZkqoN5/9/2ImxohJvUYEJYc="/></head><body></body></html>';

怎么通过jquery得到其中content的值?

本来觉得这个问题蛮简单的,既可以通过正则获取,也可以通过jquery的$将这个字符串变成一个jq对象来获取。但是也正是后来这个方法,却带来了问题。

以我的理解,定位content的方法应该为$(s).find("meta").attr("content"),但是这么去获取结果确并不正确。

于是做了简单的尝试:

var s = '<html lang="en" class="js no-touch discourse-no-touch">'+ '<head><meta name="csrf-token" content="Oul7WqVh4FBVse2yGeY8ZkqoN5/9/2ImxohJvUYEJYc="/></head><body></body></html>';
$(s);//[<meta name=​"csrf-token" content=​"Oul7WqVh4FBVse2yGeY8ZkqoN5/​9/​2ImxohJvUYEJYc=">​]

得到的并不是所详细的结果,而是meta标签。

这就有点奇怪了,风大猜测是因为外面有<html></html>,可能jquery不能把<html>标签变为dom。而在字符串外层套一层div则确实能够正确的获取结果。
但是,这个结果真的正确么?
又做了一个简单的尝试:
var s = '<div><html lang="en" class="js no-touch discourse-no-touch">'+
  '<head><meta name="csrf-token" content="Oul7WqVh4FBVse2yGeY8ZkqoN5/9/2ImxohJvUYEJYc="/></head><body></body></html></div>';
$(s);//[<div>​<meta name=​"csrf-token" content=​"Oul7WqVh4FBVse2yGeY8ZkqoN5/​9/​2ImxohJvUYEJYc=">​</div>​]

结果并不是我们所想象的那样,而是仍旧去除了html标签,只不过因为套用了一层div,使$(s).find("meta").attr("content")去正确找寻了节点,并不是保护了html标签。

这个问题的原因,相信只有jq的源码能够给我答案了。写了几行简单的测试代码,去通过断点解读一下jq的处理机制:

(function() {
        debugger;
        $('<html class="123"></html>');
        $('<div></div>');
        $('<html></html>');
    })();

事实证明,除了第一种方式不能正确的获得结果以外,后两种都能正确的获取结果。通过研读jq的源码中对jq对象创建的代码,终于弄清楚了这个原因。

jq对传入的字符串会进行一次正则:

var parsed = rsingleTag.exec( data );//rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>|)$/

解释一下这个正则吧:

^<(\w+)\s*\/?
以<开头,至少跟着一个字符和任意个空白字符,之后出现0或1次/
>
这个就不说了,前面这些加起来就是<div >这样或者<meta />这样的
(?:<\/\1>|)$
可以匹配<、一个/或者空白并以之为结尾
这些就是</div>或者跟着<br />这种自闭合标签后面的空

这样如果没有任何属性和子节点的字符串(比如'<html></html>'或者'<div></div>'这样)会通过正则的匹配,当通过正则的匹配后则会通过传入的上下文直接创建一个节点:

if ( parsed ) {
            return [ context.createElement( parsed[1] ) ];
        }//context为上下文

而未通过节点的字符串,则通过创建一个div节点,将字符串置入div的innerHTML:

tmp = tmp || safe.appendChild( context.createElement("div") );//创建divdom节点
tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];//将字符串置入div对象的innerHTML

而浏览器是不允许div内直接包含<html>的,因此会将html标签过滤。

当过滤了html之后,刚才的字符串变成了:

<head><meta name="csrf-token" content="Oul7WqVh4FBVse2yGeY8ZkqoN5/9/2ImxohJvUYEJYc="/></head><body></body>

jq会从两端向中间去寻找节点的头尾,在这里闭合标签则被寻找为meta标签。

这就是这次所得到的所有结论,总结一下:

如果你的标签是没有子节点和属性的标签,jq会通过正则判定后在你传入的上下文环境直接创建这个节点。
如果你的标签带有子节点或者属性,jq的正则不过,然后会创建一个div,把你的字符串作为div的innerHTML传入,再对div内部的dom节点遍历属性和节点,去获取class啊id啊之类的,然后再创建这个真正的节点。
但是浏览器不允许任何非frame类元素内部有html标签,会将之过滤。
在过滤了html标签后,head标签和body标签就成了两个标签,而jq是从外向内寻找包裹的标签对的,所以这两个标签没有被识别,而meta标签因为是自闭合标签,而且也是从外往内被包裹的最外层闭合标签,因此就成了获取这个标签。
大概就是这样了。

感谢阅读~同时感谢风大~

分享到:
评论

相关推荐

    提示Initialization failure-0x0000000c错误无法上网怎么办.docx

    本文将从问题的根源开始,逐步解释错误的原因、症状和解决方法。 错误原因 Initialization failure: 0x0000000c 错误通常是由于 Windows Sockets(WinSock)接口的初始化失败造成的。WinSock 是 Windows 操作系统...

    个人电脑配置PPPOE拨号宽带连接图文例程分享.pdf

    在实际场景中,用户可能会遇到一些莫名其妙的错误,例如 ADSL 莫名其妙的错误 691 问题。这种情况下,用户可以尝试解决方法,例如重新安装拨号软件、检查网卡驱动程序等。 本tutorial 是一份非常详细和实用的资源,...

    Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)

    在处理这类问题时,建议从影响范围较小的配置调整开始尝试,比如先尝试方法二中的`ini_set()`函数来临时调整。如果问题依旧,再尝试修改php.ini或者my.ini/***f文件。 另外,值得注意的是,增加执行时间和数据包...

    微信小程序蓝牙代码与错误整理

    不使用延迟可能会出现莫名其妙的错误,多见于Android端。 注意JS的异步、并发特性,特别在轮询service下的characteristic。小程序还不支持async,await(代码补全中有这两个关键字,但是编译不过)。 蓝牙的数据读写...

    Windows 7系统蓝屏处理和解决方案_1.docx

    Windows 7 系统蓝屏的错误信息通常由三部分组成:停机码、故障检查信息和错误名。停机码是用于识别已发生错误的类型错误的代码,被括号括起来的四个数字集是随机的开发人员定义的参数,错误名是错误的简洁描述。...

    WindowsXP下的PHP+MYSQL环境配置详解

    现在网络很流行PHP,对于初学者配置PHP环境不是容易的事,特别是在XP下,因为有IIS的缘故,经常有莫名其妙的错误。本资源详细介绍了WinXP下对于PHP环境的配置,其中各程序版本为:Apache2.24、PHP5.23、MYSQL5,另外...

    鼠标键盘自动点击小程序

    在网上下载的鼠标键盘自动点击小程序, 但是运行不了好久, c盘就满了,系统出现些莫名其妙的错误。将c盘的东西做了些专业,并换了一个鼠标小程序,发现还是有这个问题 开始的时候以为小程序有毒, 但是360没有报...

    电脑蓝屏对照码

    ◆错误分析:这个内存管理错误往往是由硬件引起的, 比如: 新安装的硬件、内存本身有问题等. ◇解决方案:如果是在安装Windows时出现, 有可能是由于你的电脑达不到安装Windows的最小内存和磁盘要求. 4、0x0000001E:...

    Windows7电脑蓝屏代码大全.docx

    6. 检查系统日志:在开始菜单中输入:EventVwr.msc,回车出现事件查看器,注意检查其中的系统日志和应用程序日志中表明错误的项。 7. 查询蓝屏代码:把蓝屏中密密麻麻的 E 文记下来,接着到其他电脑中上网 进入微软...

    电脑开机蓝屏,电脑蓝屏解决方法.docx

    6. 检查系统日志:在开始--菜单中输入:EventVwr.msc,回车出现事件查看器,注意检查其中的系统日志和应用程序日志中表明错误的项。 7. 查询停机码:把蓝屏中密密麻麻的 E 文记下来,接着到其他电脑中上网查询停机码...

    电脑出现蓝屏 蓝屏故障解决方法大全

    6. 检查系统日志:在开始 --&gt; 菜单中输入 :EventVwr.msc, 回车出现 \"事件查看器\", 注意检查其中的 \"系统日志\" 和 \"应用程序日志\" 中表明 \"错误\" 的项。 7. 查询停机码:停机码可以作为搜索项在微软知识库和...

    山东省龙口市诸由观镇诸由中学九年级英语全册《Unit 6 Sad movies make me cry》练习(无答案) 鲁教版五

    这篇资料是针对山东省龙口市诸由观镇诸由中学九年级学生的英语学习材料,主要涵盖了鲁教版五四制教材的第六单元《Sad movies make me cry》的相关练习。以下是本单元涉及的重要知识点: 1. 词汇变形: - Drive:...

    解决Windows7资源管理器失去响应.docx

    - **电源管理设置不当**: 错误的电源管理设置可能导致硬盘意外关闭。 **解决方案** - **更新驱动**: 更新显卡、主板及网卡等硬件驱动至最新版本,优先选择通过WHQL认证的驱动。 - **调整电源管理设置**: 将电源管理...

    快乐秒赞 v1.6 授权版.zip

    1.解密所有加密的源码,基本修复php代码错误 2.去除全部后门代码。 3.去除授权机制。 4.邮件发送改用本地smtp,不用官方API 5.单向检测、VIP签到均改用本地接口 6.增加SAE的支持 7.增加找回密码功能 8.修复...

    AndroidStudio是最难用的IDE,没有之一

    这几天试图用Android...各种莫名其妙的错误。比如说,如果某个依赖库找不到,这个是比较常见的,要么下载要么路径不对,设置一下就可以了。而AndroidStudio则是你想象不到的地方出错。 提示没有用。莫名其妙,不知所

    蓝屏代码查询器 2.1.3.zip

    在“开始\运行”中输入“EventVwr.msc”,回车后打开“事件查看器”,注意检查其中的“系统日志”和“应用程序日志”中标明“错误”的项。 7、查询停机码 把蓝屏中密密麻麻的E文记下来,用本工具查询,一般情况下,...

    超好用的注册表清理器,直接解压即可使用

    在日常使用电脑的过程中,我们经常会遇到系统运行缓慢或者出现各种莫名其妙的问题,这些问题往往和系统注册表有关。注册表是Windows操作系统中重要的组成部分,它记录着各种软硬件配置和用户设置信息。随着系统使用...

    QGIS3.2二次开发流程介绍

    在编译源码时,可能会遇到各种莫名其妙的C++语法错误。解决这一问题的方法是修改源文件的编码。具体来说,可以在VS中全选.cpp文件,将其编码格式改为UTF-8带签名。此外,还需要加载指定的qgis运行所需的项目,并编译...

Global site tag (gtag.js) - Google Analytics