Торнадо поставил запрос на пропажу тела
Я пытаюсь сделать запрос put, используя tornado ASyncHTTPClient, например:
data = { 'text': 'important text',
'timestamp': 'an iso timestamp' }
request = tornado.httpclient.HTTPRequest(URL, method = 'PUT', body = urllib.urlencode(data))
response = yield Task(tornado.httpclient.ASyncHTTPClient().fetch, request)
Однако, когда запрос достигает желаемой конечной точки, он, по-видимому, не имеет тела, несмотря на то, что это тело было правильно закодировано и определено выше. Есть ли что-то, что я упускаю из виду?
3 ответа:
Если другой конец ожидает JSON, вам, вероятно, нужно установить заголовок "Content-Type". Попробуйте это:
data = { 'text': 'important text', 'timestamp': 'an iso timestamp' } headers = {'Content-Type': 'application/json; charset=UTF-8'} request = tornado.httpclient.HTTPRequest(URL, method = 'PUT', headers = headers, body = simplejson.dumps(data)) response = yield Task(tornado.httpclient.ASyncHTTPClient().fetch, request)
Таким образом, заголовок сообщает серверу, что вы отправляете JSON, а тело-это строка, которая может быть проанализирована как JSON.
Вопрос, вероятно, на другом конце.
Следующий тест с использованием Tornado 2.4.1 дает ожидаемый результат.import logging import urllib from tornado.ioloop import IOLoop from tornado.web import Application, RequestHandler, asynchronous from tornado.httpclient import HTTPRequest, AsyncHTTPClient from tornado import gen, options log = logging.getLogger() options.parse_command_line() class PutBodyTest(RequestHandler): @asynchronous @gen.engine def get(self): data = { 'text': 'important text', 'timestamp': 'a timestamp' } req = HTTPRequest( 'http://localhost:8888/put_body_test', method='PUT', body=urllib.urlencode(data) ) res = yield gen.Task(AsyncHTTPClient().fetch, req) self.finish() def put(self): log.debug(self.request.body) application = Application([ (r"/put_body_test", PutBodyTest), ]) if __name__ == "__main__": application.listen(8888) IOLoop.instance().start()
Вывод журнала:
$ python put_test.py --logging=debug [D 130322 11:45:24 put_test:30] text=important+text×tamp=a+timestamp [I 130322 11:45:24 web:1462] 200 PUT /put_body_test (127.0.0.1) 0.37ms [I 130322 11:45:24 web:1462] 200 GET /put_body_test (::1) 9.76ms
Это post-запрос с ожиданием JSON! Попробуйте это:
@gen.coroutine def post(self): http_client = AsyncHTTPClient() http_client = tornado.httpclient.AsyncHTTPClient() URL = "http://localhost:1338/api/getPositionScanByDateRange" data = {"startDate":"2017-10-31 18:30:00","endDate":"2018-02-08 12:09:14","groupId":3} #A dictionary of your post data headers = {'Content-Type': 'application/json; charset=UTF-8'} record = yield http_client.fetch(URL, method = 'POST', headers = headers, body = json.dumps(data)) if record.error: response = record.error else: response = record.body self.set_header('Content-Type', 'application/json') self.finish(response)