表情符号和其他unicode字符在Angular中没有正确显示

dav*_*rty 4 unicode emoji angularjs

例如,我有一个使用Twitter消息的网络应用程序.

JSON的提要用于构建消息列表,但是诸如字符在钻石中显示为问号.元素看起来像这样:

<div class="inner-message" ng-bind-html="unit.caption_text | linky:'_blank'"></div>           
Run Code Online (Sandbox Code Playgroud)

当我在Firefox和Chrome中查看JSON url时,这些显示正常.

头部样本:

<!DOCTYPE html>
<html class="wf-opensans-n4-active wf-active" lang="en">
<head>
<meta charset="utf-8">
Run Code Online (Sandbox Code Playgroud)

我在调试时发现的一件事:当消息都在一个对象数组中,但不是$ scope的一部分时,我可以将它们添加到页面中,并且表情符号正确显示.

所以我认为在Angular中会发生这样的事情.我已经尝试将ng-bind-html更改为ng-bind,但是这样做并没有.我已经尝试删除ng-bind-html并在元素中使用{{unit.caption_text}},但它仍然会破坏unicode字符.

目前,我需要能够使用linky过滤器,以正确显示链接,因此ng-bind-html是必要的,但我不相信这是问题所在.

在javascript中发生了什么事情来打破编码?

有没有办法让它们正确显示?


更新

这会根据需要显示图标,但"linky"不会为链接添加格式.

<div class="inner-message">{{unit.text}}</div>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这显示了破碎的字符

<div class="inner-message" ng-bind-html="unit.text | linky:'_blank'"></div>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


更新2

最后到达那里,在Michael链接的Pull Request中进行详细更改,以阻止角色搞砸.

我还发现,如果我将Symbola添加到这些消息的字体堆栈中,它有助于保持一致性.您可以从George Douros的这个页面下载Symbola .我通过.ttf到.woff转换器运行它以获得稍微更好的浏览器支持,提供两种选择.

Mic*_*mza 8

注意:此帖子未在Chrome上显示,因为它不支持表情符号字符

看起来Angular的$sanitize服务试图将字符转换为它们的HTML实体等价物.但是,对于某些单个表情符号字符,它会将其拆分为2.如http://plnkr.co/edit/fDDen3bnnrQUvx3JfKgw?p=preview所示,

$scope.sanitizedText = $sanitize('');
Run Code Online (Sandbox Code Playgroud)

模板输出为

{{sanitizedText}}
Run Code Online (Sandbox Code Playgroud)

节目&#55357;&#56904;.为什么?我不知道.

这意味着任何使用$sanitize都会有效地打破这些角色.这包括

  • 使用ng-bind-html该输出显示的输出尚未完成$sce.trustAsHtml
  • 任何东西穿过linky,因为可以在可见linky源,它调用$sanitize.

所以,你可以避开HTML贯通进入$sanitize只要

  • 您通过$ sce.trustAsHtml传递字符串
  • 您没有通过Angular提供的linky过滤器传递它,而是滚动您自己的不是$sanitize输入.

下面是一个示例过滤器:

app.filter('unsafeLinky', function($sce) {
  // Regex from https://github.com/angular/angular.js/blob/master/src/ngSanitize/filter/linky.js#L5
  var urlRegex = /(((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>])/gi;
  return function(input, target) {
    var targetHTML = target ? ' target="' + target + '"' : '';
    return $sce.trustAsHtml(input.replace(urlRegex,'<a href="$1"' + targetHTML + '>$1</a>'));
  }
});
Run Code Online (Sandbox Code Playgroud)

哪个可以用作

<p ng-bind-html="text | unsafeLinky:'_blank'"></p>
Run Code Online (Sandbox Code Playgroud)

您可以在http://plnkr.co/edit/sRJmt4YVO8udJInCd4Cy?p=preview上看到此演示

正如名称所示,这个不安全的链接过滤器是不安全的.请务必相信原始文本的来源.

正如本答案开头所示,Chrome无法正确显示表情符号字符.要获取Chrome中显示的字符,您可能必须使用某种图像替换.无论如何,我怀疑这超出了这个特定问题的范围.

更新

Angular有PR可能会解决这个问题,一旦合并完成就不需要上面的解决方法:https://github.com/angular/angular.js/pull/6911