【问题标题】:alamofire request gets text/html response, while curl and postman get json responsealamofire 请求获取 text/html 响应,而 curl 和 postman 获取 json 响应
【发布时间】:2019-09-30 23:12:34
【问题描述】:

==================================

注意:使用@Larme 的技巧打印出请求的 debugDescription,并与我的工作 curl 请求进行比较,我能够找出我所做的愚蠢错误。 1. 在服务器请求处理程序中,当某些东西无法识别时,我会返回一个 serializerError,非常令人困惑。 2. 我在 swift 的请求中犯了一个愚蠢的错误,将“GET_RECIPES”而不是“GET_RECIPE”。

=================================

我有一个使用 django rest 框架实现的 http 服务,当我通过 swift/alamofire 发送请求时,它无法获得正确的 json 响应。但是,通过 curl 和 postman 发送的请求会得到正确的 json 响应。 所以我很困惑问题出在哪里,django 服务端还是 swift 请求端?

  1. 我曾尝试在swift中使用.responseString而不是.responseJSON来打印resposne,但是响应中仍然没有数据,基本上是在请求到达服务器端时发生错误。
  2. 从 django 服务器端,错误显示为“TypeError:'property' 类型的对象不是 JSON 可序列化的”。好的,看来问题出在 django 方面...
  3. 但是通过 curl 和 postman,我可以毫无问题地获得 json 响应,响应标头包含“Content-Type”:“application/json”,对于 django 端来说,一切都还可以。那么这是否意味着django服务器可以处理json响应,应该是swift请求的问题??

快速编写代码,

let parameters: [String: Any] = [
    "type": "GET_RECIPE",
    "details": ["ingredients" : ["egg", "bread"]]
]
let headers = ["Content-Type": "application/json"]
Alamofire.request(url, mothod: .post, parameters: parameters, 
                  headers: headers, encoding: JSONEncoding.default)
                .responseJSON {response in
                if let data = response.result.value {
                    print(data)
                }
}

请求处理程序的代码

class RecipesSerilizer(serializers.ModelSerializer):
    class Meta:
        model = Recipes
        fields = ('id', 'url', 'author', 'category', 'title', 'description',
                  'instructions', 'tip', 'raw', 'score')

def get_recipes_given_ingredients(data):
    logger.info('Get recipes for {}'.format(data.get('details')))
    details = data.get('details')
    ingredients = details.get('ingredients')
    logger.info('GET_RECIPE for ingredients {}'.format(ingredients))
    recipes = queries.get_recipe_recommendation_given_ingredients(ingredients)
    serializer = RecipesSerilizer(recipes, many=True)
    return Response(serializer.data)

来自服务器端的跟踪堆栈:

Internal Server Error: /get-recipes/
Traceback (most recent call last):
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\django\core\handlers\base.py", line 145, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\django\core\handlers\base.py", line 143, in _get_response
    response = response.render()
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\django\template\response.py", line 106, in render
    self.content = self.rendered_content
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\response.py", line 72, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\renderers.py", line 733, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\renderers.py", line 688, in get_context
    'content': self.get_content(renderer, data, accepted_media_type, renderer_context),
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\renderers.py", line 424, in get_content
    content = renderer.render(data, accepted_media_type, renderer_context)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\renderers.py", line 107, in render
    allow_nan=not self.strict, separators=separators
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\utils\json.py", line 28, in dumps
    return json.dumps(*args, **kwargs)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\json\encoder.py", line 201, in encode
    chunks = list(chunks)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\json\encoder.py", line 437, in _iterencode
    o = _default(o)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\site-packages\rest_framework\utils\encoders.py", line 68, in default
    return super(JSONEncoder, self).default(obj)
  File "C:\Users\Yuanjun\Anaconda2\envs\online_bid\lib\json\encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'property' is not JSON serializable
[14/May/2019 08:29:32] "POST /get-recipes/ HTTP/1.1" 500 124585

【问题讨论】:

  • 我以前见过这个,它取决于 url 上是否有斜杠。这将是一个快速测试,看看这是否能解决您的问题。
  • @Don 感谢您的建议。我确实在网址上有斜杠。删除尾部斜杠确实会在 http 响应中引发 500 代码,但它与 django 端的运行时错误不同。
  • 抱歉,我无法提供更多帮助。我的后端开发人员从未解释过它为何如此重要。希望有人知道。
  • 你能显示邮递员请求的详细信息吗?
  • 你有卷曲工作吗?然后不要做Alamofire.request(...).responseJSON{...},而是做let request = Alamofire.request(...); print(request.debugDescription); request.responseJSON{...},比较输出。我在那里解释了 (stackoverflow.com/questions/53637437/alamofire-with-d/…) 诀窍

标签: swift django-rest-framework alamofire


【解决方案1】:

我认为您的问题是您正在尝试将帖子发送到获取请求。

尝试如下更改您的 alamofire 请求:

let parameters: [String: Any] = [
    "type": "GET_RECIPE",
    "details": ["ingredients" : ["egg", "bread"]]
]
let headers = ["Content-Type": "application/json"]
Alamofire.request(url, mothod: .get, parameters: parameters, 
                  headers: headers, encoding: JSONEncoding.default)
                .responseJSON {response in
                if let data = response.result.value {
                    print(data)
                }
}

【讨论】:

  • 不,我实现了 django post 处理程序,虽然我承认端点的名称有点误导。我可以 curl 或 postman 使用 post 请求来获取响应。
【解决方案2】:

可能服务器在处理您的请求时崩溃或找不到给定的 URL(因为尾部斜杠)。 如果服务器在DEBUG 模式下运行时崩溃,通常会返回text/html。这就是它通过堆栈跟踪以漂亮的方式显示崩溃原因的方式。

很难说你的情况发生了什么。如果您提供错误的堆栈跟踪,那就太好了。

【讨论】:

  • 你是对的,服务器运行在DEBUG模式。这不是由于斜线。我编辑原始问题以从服务器端发布跟踪堆栈。 TypeError: Object of type 'property' is not JSON serializable 出现了,但是当使用 curl 或 postman 发送相同的 post 请求时,它工作得很好。这让我很困惑。
  • @YuanjunZhou 似乎此语句返回错误和意外数据recipes = queries.get_recipe_recommendation_given_ingredients(ingredients)。你能抓住它的结果吗?另外,我建议使用基于类的视图,例如来自rest_frameworkAPIView
猜你喜欢
  • 2015-06-20
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-13
相关资源
最近更新 更多