好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

中文乱码?不,是HTML实体编码!_html/css_WEB-ITnose

When question comes

在 如何用 Nodejs 分析一个简单页面 一文中,我们爬取了博客园首页的 20 篇文章标题, 输出部分拼接了一个字符串:

var $ = cheerio.load(sres.text);var ans = '';$('.titlelnk').each(function (index, item) {  var $item = $(item);  ans += $item.html() + '  ';});// 将内容呈现到页面res.send(ans); 

页面呈现良好:

但是查看网页源代码,却看到这样的情景:

什么鬼?我们让问题再清晰些,试着把爬虫代码稍做修改:

var $ = cheerio.load(sres.text);var ans = [];$('.titlelnk').each(function (index, item) {  var $item = $(item);  ans.push($item.html());});// 将内容呈现到页面res.send(ans); 

这 输出的是什么玩意儿?

乱码?不,是 HTML 实体编码!

HTML 实体编码

在 HTML 中,某些字符是预留的, 比如不能使用小于号( ),这是因为浏览器会误认为它们是标签 。如果希望正确地显示预留字符,我们必须在 HTML 源代码中使用字符实体(character entities)。当然还另一个重要原因,有些字符在 ASCII 字符集中没有定义,因此需要使用字符实体来表示,比如中文。

字符实体类似这样:

&entity_name;或者&#entity_number; 

如需显示小于号,我们必须这样写: < 或 < 。前者(实体名)易于记忆,而后者(实体数字)在浏览器中的支持较好。

HTML 中常见的需要替换成字符实体的字符有 4 个,分别是 、 & 以及 " 。为此,我们可以简单写个 escapeHTML 函数(使得网页上可以正确显示这 4 个字符,而不会被误认为是标签):

function escapeHTML(text) {      var replacements= {" ": ">","&": "&", """: """};                          return text.replace(/[ &"]/g, function(character) {          return replacements[character];      }); } 

更多关于 HTML 实体编码的内容可以参考 HTML 字符实体

Solution

不仅是 " " 这样的能编码, 所有字符均能编码 ,这也是出现 "乱码" 的原因。在文章开头的例子中,其实它把该 target 标签内的所有东西(包括中文)都给编码了。

而最开始的代码(字符串 输出)之所以没有 "乱码",完全是因为浏览器自动帮你解码了。(如果存在于 HTML 代码中,会被自动解码)

知道了原因,我们可以从两个方向解决问题。

首先, 我们可以不对其内容进行编码 。用 text() 方法取代 html() 方法:

$('.titlelnk').each(function (index, item) {  var $item = $(item);  ans.push($item.text());}); 

很简单并且完美地解决了这个问题。

如果说不能从编码的角度解决,我们可以试着解码。

方法一:

创建空标签,将编码内容用 html() 方法塞入,用 text() 取出,转换过程让第三方完成(当然前提是获取了 $ 对象):

  function htmlDecode(str) {     var t = $("

查看更多关于中文乱码?不,是HTML实体编码!_html/css_WEB-ITnose的详细内容...

  阅读:36次