Использование Content-Type:application/json для публикации в curl дает HTTP/1.1 400 BAD REQUEST

Когда я делаю почтовый запрос, используя следующее

curl -i -d "username=rock&password=rock" http://my_VM_IP/api/1.1/json/my_login/

он генерирует требуемый ответ, генерируя такой токен (сокращенно):

HTTP/1.1 200 OK
Date: Mon, 22 Oct 2012 08:37:39 GMT
Vary: Authorization,Accept-Language,Cookie,Accept-Encoding
Content-Type: text/plain
Transfer-Encoding: chunked
OK{"success": {"my_token": "required_token"}}

Но когда я пытаюсь сделать то же самое, включая заголовок, как:

curl -i -H "Content-Type:application/json" -d "username=rock&password=rock" http://my_VM_IP/api/1.1/json/my_login/ 

это дает мне следующую ошибку:

HTTP/1.1 400 BAD REQUEST
Date: Mon, 22 Oct 2012 11:12:04 GMT
Vary: Authorization,Accept-Language,Cookie,Accept-Encoding
***Content-Type: text/plain***
Content-Language: en-us
Connection: close
Transfer-Encoding: chunked
Bad Request

Я не понимаю, почему это происходит. А также почему тип содержимого показывает text/plain, я также пытался рассмотреть некоторые другие вопросы, такие как Почему установка POST Content-type:Application/Json вызывает неверный запрос в REST WebService? . Он также решает ту же проблему, что и у меня. После ответа в том, что я попытался предоставить данные в различных форматах как

{"username":"rock", "password":"rock"} 

но безуспешно. Заранее спасибо.


person The Recruit    schedule 22.10.2012    source источник


Ответы (3)


Используя -H "Content-Type:application/json", вы устанавливаете заголовок Content-Type для своего запроса. Ответ по-прежнему будет возвращать то, что ваше представление говорит ему возвращать.

Чтобы вернуть ответ с Content-Type application/json, используйте что-то вроде этих строк:

import json
from django.http import HttpResponse

def json_response(return_vars):
    'JSON-encodes return_vars returns it in an HttpResponse with a JSON mimetype'
    return HttpResponse(json.dumps(return_vars), content_type = "application/json")

#Usage: return json_response({'admin_token': admin_api_token.token})
person Anuj Gupta    schedule 22.10.2012
comment
Я был бы рад, если бы вы могли уточнить lil. В настоящее время я просто возвращаю токен следующим образом: Обо всех исключениях позаботятся. - person The Recruit; 23.10.2012
comment
Все, что вам нужно сделать, это 1) JSON-кодировать ваши данные и 2) добавить content_type = "application/json" в конструктор HttpResponse. В вашем случае HttpResponse возвращается json_success_response. - person Anuj Gupta; 23.10.2012
comment
Добавление content_type не имеет никакого эффекта.. и добавление Content-Type в качестве возврата HttpResponse(json.dumps(response),Content-Type = application/json) дает SyntaxError: ключевое слово не может быть выражением - person The Recruit; 23.10.2012
comment
Нет никаких причин, по которым content_type = "application/json" не работает, это прямо из документы. Другой пример использования: file-attachment" rel="nofollow noreferrer">здесь. - person Anuj Gupta; 23.10.2012
comment
В зависимости от вашего кода я бы попробовал response = json_success_response({'admin_token': admin_api_token.token}); response['Content-Type'] = 'application/json'); return response - person Anuj Gupta; 23.10.2012

Вы были близки, но вам нужно отправить его в формате JSON через curl:

curl -i -H "Content-Type:application/json" -d '{"username":"rock", "password":"rock"}'

("password","admin" должно быть "password":"admin")


Если это не работает, попробуйте:

curl --dump-header - -H "Accept:application/json" -H "Content-Type:application/json" -X POST --data '{"username": "admin", "password": "admin"}' http://my_VM_IP/api/1.1/json/my_login/
person K Z    schedule 22.10.2012
comment
Большое спасибо за ваш ответ. Что ж, это была опечатка, которую я исправил. Если бы вы могли сказать мне, пожалуйста, почему он все еще показывает этот Content-Type: text/plain - person The Recruit; 22.10.2012
comment
@TheRecruit посмотрите другие ответы, возможно, вы неправильно установили content-type в своем ответе. - person K Z; 22.10.2012

Когда вы устанавливаете параметр -H команды curl, вы указываете тип содержимого запроса. Тип содержимого ответа, который вы видите в ответе, устанавливается на сервере. В приложении WSGI вам нужно указать 'content-type' и 'content-length' вручную. Некоторые фреймворки предоставляют служебный метод для возврата ответов JSON (например, метод jsonify в Flask).

person Marboni    schedule 22.10.2012