如何 HTML 从服务器转义 Backbone.js 中的字符串?

How to HTML escape strings from the server in Backbone.js?

我正在 Rails 应用程序上处理大型遗留 Ruby,它没有脚本注入保护 (例如,您可以在某人的地址中输入 <script>console.log('hackd')<script> ,保存,加载页面时代码会运行).

该应用程序还将一些自定义 HTML 标签插入到我们的模板渲染中。因此我们不能在我们的 EJS 模板中使用转义函数 <%-,因为我们需要显示这个 HTML。

所以我认为转义数据的最佳位置是数据从服务器到达浏览器时,如下所示:

  Backbone.Model.prototype.parse = function(resp, options) {
    return escapeStringsRecursively(resp);
  }

  function escapeStringsRecursively(o) { //https://github.com/wesleytodd/recursive-escape/blob/master/index.js
    if (typeof o === 'undefined' || o === null)
      return o;
    if (o instanceof Array)
      for (var i = 0; i < o.length; i++) {
        o[i] = escapeStringsRecursively(o[i]); }
    else if (typeof o === 'object')
      for (var i in o) {
        if (o.hasOwnProperty(i))
          o[i] = escapeStringsRecursively(o[i]); }
    else if (typeof o === 'string')
      o = _.escape(o);
    return o;
  }

下面是正在发生的事情的 .gif。

当我第一次加载页面时,您可以看到我的解析方法捕获其中包含 script 的字符串,并使用漂亮的 HTML 将它们转义到屏幕。然后我导航到另一个页面并 return。现在该方法永远不会触发,页面已损坏,脚本标签有 运行 console.errors:

除了 Backbone.Model.prototype.parse 之外,我们还在 Backbone.Collection.prototype.parse 上添加了解析,因为我们发现 Model 仅在第一个页面加载时被调用,但 Collection 在所有页面加载时都被调用。

然后我们不得不更改转义代码以避免双重转义:o = _.escape(_.unescape(o)); 因为 Collection 和 Model 会在第一次双重转义。

我们不知道为什么 Model.parse 没有在随后的 Backbone.fetches 中被调用,但这个解决方法是可以的。