Lodash原始碼分析-escape.js

DrMoon發表於2017-12-20

前言

本系列使用 lodash 4.17.4版本

此方法沒有對其他方法進行引用

正文

原始碼

/** Used to map characters to HTML entities. */
const htmlEscapes = {
  '&': '&amp',
  '<': '&lt',
  '>': '&gt',
  '"': '&quot',
  "'": '&#39'
}

/** Used to match HTML entities and HTML characters. */
const reUnescapedHtml = /[&<>"']/g
const reHasUnescapedHtml = RegExp(reUnescapedHtml.source)

/**
 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
 * corresponding HTML entities.
 *
 * **Note:** No other characters are escaped. To escape additional
 * characters use a third-party library like [_he_](https://mths.be/he).
 *
 * Though the ">" character is escaped for symmetry, characters like
 * ">" and "/" don't need escaping in HTML and have no special meaning
 * unless they're part of a tag or unquoted attribute value. See
 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
 * (under "semi-related fun fact") for more details.
 *
 * When working with HTML you should always
 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
 * XSS vectors.
 *
 * @since 0.1.0
 * @category String
 * @param {string} [string=''] The string to escape.
 * @returns {string} Returns the escaped string.
 * @see escapeRegExp, unescape
 * @example
 *
 * escape('fred, barney, & pebbles')
 * // => 'fred, barney, &amp pebbles'
 */
function escape(string) {
  return (string && reHasUnescapedHtml.test(string))
    ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr])
    : string
}

export default escape
複製程式碼

解析

引數

該方法只接受一個引數,準備被轉義html實體的引數。

返回值

該方法返回被轉義了實體的字串。

方法解析

1.該方法會首先定義一個htmlEscapes物件,這個物件就是將被轉義的html實體的對映物件。物件的屬性是字元,屬性值是對應的html實體。

2.該方法會定義一個RegExp型別的物件reUnescapedHtml,並將reUnescapedHtml物件模式匹配所用的文字賦值給另一個RegExp變數reHasUnescapedHtml

3.接下來是方法的主函式,這裡會先判斷傳入的引數轉換為布林值後是否為假以及若為真後是否可以匹配到欲轉義的字元,如果為假或者未匹配到字元則直接將傳入的引數原樣返回給呼叫該方法的地方;若為真並且匹配到了字元,就會用到正則的replace方法依照最先定義的htmlEscapes物件中的字元與html實體的對應將傳入字串中對應的字元轉義為html實體,之後將轉義後的字串返回給呼叫該方法的地方。

注: 該方法可被轉義的字元為:&<>"'

注: 因為只有字串可以匹配到正則規則中的字元,所以其他型別的值由於不會匹配到字元會被直接返回給方法呼叫的地方。

示例

escape("<javascript>alert('I love Script!')</javascript>");
--> "&ltjavascript&gtalert(&#39I love Script!&#39)&lt/javascript&gt"
escape(2333);
--> 2333
escape({a: "<javascript>alert('I love Script!')</javascript>", b: "'Javascript is the best!'"});
--> {a: "<javascript>alert('I love Script!')</javascript>", b: "'Javascript is the best!'"}
escape(true);
--> true
escape(null);
--> null
escape(undefined);
--> undefined
複製程式碼

總結

某些人會在Web頁面裡插入惡意的Script程式碼,當使用者瀏覽該頁之時,嵌入其中Web裡面的Script程式碼會被執行,從而達到惡意攻擊使用者的目的,由於該方法可將字串中的幾個特殊字元轉義為html實體,使嵌入的Script程式碼無法執行,這樣可以防止XXS(跨站指令碼攻擊)。

具體的XSS方面知識這裡就不詳細講述了(其實是因為我也知道的不多哈),感興趣的可以自行搜尋瞭解。

相關連結:

每日原始碼分析 - lodash(debounce.js和throttle.js)

每日原始碼分析 - lodash(remove.js)

本文章來源於午安煎餅計劃Web組 - 殘陽

相關文章