我将网站的前端从旧的YUI2框架迁移到jQuery / BackBone。 PHP / mySQL后端没有改变。一切都很好,除了通过Backbone保存(通过$ .ajax)发送的UTF-8字符越来越严重,我无法弄清楚原因。
这是我所知道的:
escape(string)
在Javascript中转义,通过YAHOO.util.Connect.asyncRequest
作为JSON传递到XMLHttpRequest
,未转义并以UTF-8格式保存在数据库中,完全可读且不错。<meta charset="UTF-8">
和<meta http-equiv="content-type" content="text/html; charset=UTF-8">
添加到所有页面标题中。旧的前端没有这些设置。我只提到它,因为它有所不同。<form>
提交时,UTF-8字符可以正常工作。Content-Type:application/x-www-form-urlencoded; charset=UTF-8
我如何在新的前端传递数据?
有时通过常规的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异步请求传递的特定格式而构建的。我不知道。
我接下来要尝试的任何想法?什么是最佳实践?
答案 0 :(得分:2)
现在我已经睡上了一夜,我已经意识到了一些事情,我想我已经找到了解决方案。
现在很清楚,旧的前端没有正确传递数据......控制台中的text: (unable to decode value)
证明了这一点\ n&nbsp;发送请求时不知何故,即使api或db存储类中没有解码,PHP后端也能够处理传递的文本。这对另一天来说是一个谜。
以下是解决问题的方法:
encodeURIComponent(text)
$comment->set_text(urldecode(Request::get('text')));
文本存储在未转义为可读UTF-8字符的数据库中,我不需要在读取/显示上做任何特殊操作。我需要将urldecode
添加到后端的所有api端点,但这感觉就像一个可靠的方法,所以我认为它已经解决了。
我有兴趣听听有关在前端使用encodeURIComponent
和在后端使用urldecode
的想法。这是解决问题的最佳方法吗?