Flask-Restful API 中的 Unicode 和 JSON 问题

Posted

技术标签:

【中文标题】Flask-Restful API 中的 Unicode 和 JSON 问题【英文标题】:Unicode in Flask-Restful API and JSON issue 【发布时间】:2013-10-25 15:42:46 【问题描述】:

我遇到了一个与 Flask-Restful API 服务器的 ajax 请求中的 unicode 相关的奇怪问题。该问题仅出现在一台机器上,而不会出现在另一台机器上。

我的课很安静。正如您可能注意到的,字符字段设置为 unicode。

class PostListApi(Resource):
def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('body', type = unicode, required = True, help = 'No description provided', location = 'json')
        self.reqparse.add_argument('longitude', type = float, required = False, help = 'Unknown address', location = 'json')
        self.reqparse.add_argument('latitude', type = float, required = False, help = 'Unknown address', location = 'json')
        self.reqparse.add_argument('address', type = unicode, required = True, help = 'No address specified', location = 'json')
        self.reqparse.add_argument('scheduled', type = str, required = True, help = 'Not scheduled correctly', location = 'json')
        super(PostListApi, self).__init__()

我的问题是,当我在 BODY 中发送带有拉丁字符的 ajax 请求时,服务器会回复 400 错误。

Request URL:
Request Method:POST
Status Code:400 BAD REQUEST
Request Headersview source
Accept:undefined
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Content-Length:159
**Content-Type:application/json; charset=UTF-8**
Proxy-Authorization:Basic a3lyeWxvLnlhdHNlbmtvOnBhc3N3b3JkMTIzNDU2
Proxy-Connection:keep-alive
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/28.0.1500.95 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payloadview parsed
"body":"this is a test","address":"141 Rue Saint-Martin, 75003 Paris, France","longitude":2.351530499999967,"latitude":48.8614575,"scheduled":"20131017 1000"

但是当数据是西里尔字母时,服务器会正​​确管理请求。

Request URL:
Request Method:POST
Status Code:500 INTERNAL SERVER ERROR
Request Headersview source
Accept:undefined
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Content-Length:208
**Content-Type:application/json; charset=UTF-8**
Cookie:
Proxy-Authorization:Basic a3lyeWxvLnlhdHNlbmtvOnBhc3N3b3JkMTIzNDU2
Proxy-Connection:keep-alive
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payloadview source
body:Йн незл ножтрюд оффÑндйт вÑш,…
address: "Йн незл ножтрюд оффÑндйт вÑш"
body: "Йн незл ножтрюд оффÑндйт вÑш"
latitude: 48.8614575
longitude: 2.351530499999967
scheduled: "20131017 1000"
Response Headersview source
Connection:Keep-Alive
Content-Length:51
Content-Type:application/json
Date:Thu, 17 Oct 2013 08:03:41 GMT
Proxy-Connection:Keep-Alive
Server:WSGIServer/0.1 Python/2.7.5

使用jquery的ajax方法生成请求

function ajaxRequest(uri, method, data)
    var request = 
                url: uri,
                type: method,
                contentType: "application/json; charset=utf-8",
                accepts: "application/json",
                cache: false,
                dataType: 'json',
                //data: data != null?((method == 'GET') ? $.param(data): utf8_encode(JSON.stringify(data))):null,
                data: data != null?((method == 'GET') ? $.param(data): JSON.stringify(data)):null,
                beforeSend: function (xhr) ,
                error: function(jqXHR) 
                    console.log("ajax error " + jqXHR.status);
                
            ;
    return $.ajax(request);

您以前遇到过类似的问题吗?如何解决这个问题?我想在发送到服务器之前,拉丁字符也必须编码为 un​​icode。如何强制 jquery 将所有内容编码为 un​​icode?​​p>

提前致谢!

【问题讨论】:

'当数据是西里尔字母时,服务器会正​​确管理请求。'从您以西里尔文发送内容时发布的第三段代码来看,服务器以 500 代码响应 - 内部服务器错误,所以这也不好。你在服务器上只有那个 PostListApi 类吗?一些路由和视图功能怎么样? 我不确定你的问题。如果文本是 in 西里尔文,服务器不会响应 500 代码。当文本为拉丁文时出现 400 错误(未找到参数)(第一个请求示例)。 @ryzhiy:响应包含"Status Code:500 INTERNAL SERVER ERROR"。你怎么得到的?你如何生成输出,你能显示repr()吗? 【参考方案1】:

我使用跟随代码,我没有这个问题和输出问题

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from flask import Flask
from flask.ext.restful import Api
from flask.ext.restful.representations.json import output_json
output_json.func_globals['settings'] = 'ensure_ascii': False, 'encoding': 'utf8'
app = Flask(__name__)
api = Api(app)
...

【讨论】:

以上是关于Flask-Restful API 中的 Unicode 和 JSON 问题的主要内容,如果未能解决你的问题,请参考以下文章

flask-restful写restful api接口

python 具有Flask-Restful的基本API服务器

Flask-RESTful API:多个复杂的端点

Flask-RESTful - 上传图片

Flask-restful API 授权。在装饰器中访问 c​​urrent_identity

如何将 flask.url_for() 与 flask-restful 一起使用?