alamofire-запрос получает текстовый / html-ответ, а curl и почтальон получают json-ответ - PullRequest
1 голос
/ 14 мая 2019

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

Примечание: Используя трюк @ Larme для распечатки debugDescription запроса и сравнивая его с моим рабочим запросом curl, я смог выяснить, какие глупые ошибки я сделал. 1. В обработчике запросов к серверу я возвращаю serializerError, когда что-то не распознается, довольно запутанно. 2. Я сделал глупую ошибку в своем запросе от swift, поставив «GET_RECIPES» вместо «GET_RECIPE».

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

У меня есть http-сервис, реализованный с помощью django rest framework. Когда я отправляю запросы через swift / alamofire, он не может получить правильный ответ json. Однако запросы, отправленные через curl и postman, получают правильный ответ json. Поэтому я не понимаю, в чем же проблема, сторона обслуживания django или сторона быстрого запроса?

  1. Я попытался использовать .responseString вместо .responseJSON в swift для распечатки resposne, но все же данные не находятся в ответе, в основном ошибка возникает, когда запрос достигает серверной стороны.
  2. Со стороны сервера django ошибка гласит: «Ошибка типа: объект типа« свойство »не поддерживает сериализацию в формате JSON». ОК, похоже, проблема со стороны Джанго ...
  3. Но от curl и почтальона я могу получить ответ json без проблем, с заголовком ответа, содержащим "Content-Type": "application / json", и для стороны django все также в порядке. Значит ли это, что сервер django может обрабатывать ответ json, и это должно быть проблемой быстрого запроса ??

Код в быстром,

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

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

Возможно, сервер падает при обработке вашего запроса или не может найти указанный URL (из-за косой черты).text/html обычно возвращается, если произошел сбой сервера при работе в режиме DEBUG.Вот как он довольно хорошо показывает причину сбоя с помощью трассировки стека.

Трудно сказать, что произошло в вашем случае.Было бы замечательно, если бы вы предоставили трассировку стека ошибки.

0 голосов
/ 14 мая 2019

Я думаю, что ваша проблема в том, что вы пытаетесь отправить сообщение на запрос на получение.

попробуйте изменить ваш запрос 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)
                }
}
...