从JSON解码到标准字符串

时间:2022-08-09 20:19:47

Hi I'm currently using a REST service to pull in data and using angular to print the data in the front end.

The issue I have is that the string that's being pulled through has escaped entities like ' instead of ' (apostrophe) eg. "has been inspired by France's most popular neighbourhood".
decodeURI doesn't seem to work at all.
I've found a workaround by creating custom filter which makes creates a dummy element, sets the innerHTML to the dummy element, then taking it's innerHTML once it's been parsed and returning that value.

你好,我目前正在使用一个REST服务来提取数据,并使用角度来打印前端的数据。我的问题是被拉过的字符串已经转义了像#39这样的实体;而不是(撇号)。“受到了法国最受欢迎的街区的启发”。decodeURI似乎一点作用都没有。我通过创建自定义过滤器找到了一种解决方案,该过滤器创建一个假元素,将innerHTML设置为假元素,然后在解析后获取innerHTML并返回该值。

.filter("decoder", function() {
  return function(item) {
    var txt = item;
    var dummy = document.createElement('p');
    dummy.innerHTML = txt;
    txt = dummy.innerHTML;
    dummy.remove();
    return txt;
  }
})

It feels really dirty so I was wondering if their was a way to avoid DOM manipulation for this.
Thanks!

感觉真的很脏,所以我想知道这是否是避免DOM操作的一种方法。谢谢!

2 个解决方案

#1


3  

You could manually replace each of them.

您可以手动替换其中的每一个。

.filter("decoder", function () {
  return function (item) {
    return item
      .replace(/'/g, "'")
      .replace(/"/g, '"')
      .replace(/&/g, "&")
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">");
  }
})

I think this list covers all of them, but you can always add to it if you see anything else. It's still a bit messy, but I think it's better than adding an element to the DOM.

我认为这个列表涵盖了所有这些,但是如果你看到了其他的东西,你总是可以添加到其中。这仍然有点混乱,但我认为这比向DOM添加元素要好。

UPDATE

更新

If you're looking for a more complete solution, you can do the following:

如果你正在寻找一个更完整的解决方案,你可以做以下事情:

.filter("decoder", function () {
  return function (item) {
    // it would be better to define this globally as opposed to within the function
    var ENTITIES = {
      '&amp': '&',
      '&amp;': '&',
      '&apos': '\'',
      '&apos;': '\'',
      '&gt': '>',
      '&gt;': '>',
      '&lt': '<',
      '&lt;': '<',
      '&quot': '"',
      '&quot;': '"'
    };
    return item.replace(/&#?[0-9a-zA-Z]+;?/g, function (entity) {
      if (entity.charAt(1) === '#') { // if it's a numeric entity
        var code;

        if (entity.charAt(2).toLowerCase() === 'x') { // if it's a hex code
          code = parseInt(entity.substr(3), 16);
        } else {
          code = parseInt(entity.substr(2));
        }

        if (isNaN(code) || code < -32768 || code > 65535) { // if it's not a valid numeric entity
          return '';
        }
        return String.fromCharCode(code);
      }
      return ENTITIES[entity] || entity;
    });
  }
});

As you can see, this solution is significantly more complex, but it does cover the normal entities as well as the all of the numeric ones. If your goal is to avoid updating in the future, this is your best bet.

正如您所看到的,这个解决方案要复杂得多,但是它确实覆盖了正常实体和所有数值实体。如果你的目标是在未来避免更新,这是你最好的选择。

#2


0  

You can use ng-bind-html instead of use filter to decode it. I think this can help you automatically decode entities in your html string.

您可以使用ng-bind-html而不是使用filter来解码它。我认为这可以帮助您自动解码html字符串中的实体。

#1


3  

You could manually replace each of them.

您可以手动替换其中的每一个。

.filter("decoder", function () {
  return function (item) {
    return item
      .replace(/&#039;/g, "'")
      .replace(/&quot;/g, '"')
      .replace(/&amp;/g, "&")
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">");
  }
})

I think this list covers all of them, but you can always add to it if you see anything else. It's still a bit messy, but I think it's better than adding an element to the DOM.

我认为这个列表涵盖了所有这些,但是如果你看到了其他的东西,你总是可以添加到其中。这仍然有点混乱,但我认为这比向DOM添加元素要好。

UPDATE

更新

If you're looking for a more complete solution, you can do the following:

如果你正在寻找一个更完整的解决方案,你可以做以下事情:

.filter("decoder", function () {
  return function (item) {
    // it would be better to define this globally as opposed to within the function
    var ENTITIES = {
      '&amp': '&',
      '&amp;': '&',
      '&apos': '\'',
      '&apos;': '\'',
      '&gt': '>',
      '&gt;': '>',
      '&lt': '<',
      '&lt;': '<',
      '&quot': '"',
      '&quot;': '"'
    };
    return item.replace(/&#?[0-9a-zA-Z]+;?/g, function (entity) {
      if (entity.charAt(1) === '#') { // if it's a numeric entity
        var code;

        if (entity.charAt(2).toLowerCase() === 'x') { // if it's a hex code
          code = parseInt(entity.substr(3), 16);
        } else {
          code = parseInt(entity.substr(2));
        }

        if (isNaN(code) || code < -32768 || code > 65535) { // if it's not a valid numeric entity
          return '';
        }
        return String.fromCharCode(code);
      }
      return ENTITIES[entity] || entity;
    });
  }
});

As you can see, this solution is significantly more complex, but it does cover the normal entities as well as the all of the numeric ones. If your goal is to avoid updating in the future, this is your best bet.

正如您所看到的,这个解决方案要复杂得多,但是它确实覆盖了正常实体和所有数值实体。如果你的目标是在未来避免更新,这是你最好的选择。

#2


0  

You can use ng-bind-html instead of use filter to decode it. I think this can help you automatically decode entities in your html string.

您可以使用ng-bind-html而不是使用filter来解码它。我认为这可以帮助您自动解码html字符串中的实体。