jQuery / Backbone是否会破坏我的UTF-8字符?

时间:2016-02-17 08:29:06

标签: javascript jquery backbone.js utf-8

我将网站的前端从旧的YUI2框架迁移到jQuery / BackBone。 PHP / mySQL后端没有改变。一切都很好,除了通过Backbone保存(通过$ .ajax)发送的UTF-8字符越来越严重,我无法弄清楚原因。

这是我所知道的:

  1. 后端处理UTF-8很好。作为重建的一部分,它没有改变。我知道这是真的,因为当我更改配置以加载旧的YUI2前端时,UTF-8字符工作正常。他们使用escape(string)在Javascript中转义,通过YAHOO.util.Connect.asyncRequest作为JSON传递到XMLHttpRequest,未转义并以UTF-8格式保存在数据库中,完全可读且不错。
  2. 在新的前端,我已将<meta charset="UTF-8"><meta http-equiv="content-type" content="text/html; charset=UTF-8">添加到所有页面标题中。旧的前端没有这些设置。我只提到它,因为它有所不同。
  3. 在新的前端,当我将它们保存为<form>提交时,UTF-8字符可以正常工作。
  4. 我是新的前端,请求Content-Type在控制台中看起来很好。 Content-Type:application/x-www-form-urlencoded; charset=UTF-8
  5. 我如何在新的前端传递数据?

    • 有时通过常规的Backbone model.save(),有时会在这样的选项中传递数据:

      var text = $('#input-' + targetId).val();
      
      var atts = {};
      atts['target_id'] = targetId;
      atts['user_id'] = userId;
      atts['text'] = text;
      
      var comment = new Comment(atts);
      
      comment.save(
          {},
          {
              type: 'POST',
              url: '/api/comment?',
              data: atts,
              processData: true,
              success: function(comment, response){
                 //success handling
              },
              error: function(model, response){
                 //error handling
              },
          },
      ); 
      

    那么,这些受损的特殊字符是什么样的?

    • 输入中输入:テクステクサンテクステクサン

    • 当我传递完全未转义时,它们在“表单数据”部分的控制台中的请求中看起来很好:text: テクス テクサン テクス テクサン,但在数据库中被错误地标记为{{1} }。也许这是一个线索,我不知道。我通过AJAX传递时总是转义用户输入的文字。

    • 当我ãã¯ã¹ ãã¯ãµã³ ãã¯ã¹ ãã¯ãµã³时,我在控制台中获得escape(text),在数据库中获得text:%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3%20%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3

    那更好,但它与使用テクス%20テクサン%20テクス%20テクサン,传递escape(text)的旧前端不同,在控制台中显示为%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3%20%u30C6%u30AF%u30B9%20%u30C6%u30AF%u30B5%u30F3并保存在数据库中未转义为テクステクサンテクステクサン

    • 当然,现在是2016年,我们都知道不应该使用text: (unable to decode value)。我们应该使用escape()代替。所以,当我encodeURIComponent()时,我在控制台中得到的是encodeURIComponent(text),它在数据库中保存为text: %E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3%20%E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3技术上有效,我可以{{1}在显示这个文本时,这真的很痛苦,而且只是掩盖了这个问题。

    • 我还尝试%E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3%20%E3%83%86%E3%82%AF%E3%82%B9%20%E3%83%86%E3%82%AF%E3%82%B5%E3%83%B3,结果如下:控制台中的decodeURIComponent,数据库中的unescape(encodeURIComponent(text))

    似乎正在进行某种双重编码,或者可能后端是为了处理通过YUI2异步请求传递的特定格式而构建的。我不知道。

    我接下来要尝试的任何想法?什么是最佳实践?

1 个答案:

答案 0 :(得分:2)

现在我已经睡上了一夜,我已经意识到了一些事情,我想我已经找到了解决方案。

现在很清楚,旧的前端没有正确传递数据......控制台中的text: (unable to decode value)证明了这一点\ n&nbsp;发送请求时不知何故,即使api或db存储类中没有解码,PHP后端也能够处理传递的文本。这对另一天来说是一个谜。

以下是解决问题的方法:

  1. 将文字从前端传递为encodeURIComponent(text)
  2. 使用$comment->set_text(urldecode(Request::get('text')));
  3. 解码PHP后端api中的文本

    文本存储在未转义为可读UTF-8字符的数据库中,我不需要在读取/显示上做任何特殊操作。我需要将urldecode添加到后端的所有api端点,但这感觉就像一个可靠的方法,所以我认为它已经解决了。

    我有兴趣听听有关在前端使用encodeURIComponent和在后端使用urldecode的想法。这是解决问题的最佳方法吗?