在 POST 请求 body 中删除了换行符? (Google 应用引擎)
Newlines removed in POST request body? (Google App Engine)
我正在 Google App Engine(不使用端点)上构建一个 REST API,允许用户上传 CSV 或 tab-delimited 文件并搜索可能的重复项。由于它是一个 API,我不能使用 <form>
或 BlobStore 的 upload_url
。我也不能指望有一个 Web 客户端会调用它 API。相反,理想情况下,用户将在请求的 body
中发送文件。
我的问题是,当我尝试读取 tab-delimited 文件的内容时,我发现所有换行符都已被删除,因此无法将内容拆分成行。
如果我直接在 Python 解释器上检查文件的内容,我看到那里有制表符和换行符(输出在示例中被截断)
>>> with open('./data/occ_sample.txt') as o:
... o.read()
...
'id\ttype\tmodified\tlanguage\trights\n123456\tPhysicalObject\t2015-11-11 11:50:59.0\ten\thttp://creativecommons.org/licenses/by-nc/3.0\n...'
RequestHandler
记录请求的内容 body:
import logging
class ReportApi(webapp2.RequestHandler):
def post(self):
logging.info(self.request.body)
...
所以当我通过 curl
在 dev_appserver
中调用 API 运行
curl -X POST -d @data/occ_sample.txt http://localhost:8080/api/v0/report
这显示在日志中:
id type modified language rights123456 PhysicalObject 2015-11-11 11:50:59.0 en http://creativecommons.org/licenses/by-nc/3.0
如您所见,headers 的最后一个值和第一个记录(分别为 rights
和 123456
)之间没有任何内容,最后一个值也是如此每条记录和下一条记录的第一个。
我是不是遗漏了什么明显的东西?我尝试用 self.request.body
、self.request.body_file
和 self.request.POST
加载数据,none 似乎有效。我还尝试在请求 headers 中应用 Content-Type
值 text/csv
、text/plain
、application/csv
,但没有成功。我应该添加不同的 Content-Type
吗?
您使用了错误的 curl
command-line 选项来发送您的文件数据,这个选项 正在删除换行符。
-d
选项 解析您的数据 并发送一个 application/x-www-form-urlencoded
请求,它 去除换行符 .来自 curl
manpage:
-d, --data <data>
[...]
If you start the data with the letter @
, the rest should be a file name to read the data from, or -
if you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a file named 'foobar'
would thus be done with --data @foobar
. When --data
is told to read from a file like that, carriage returns and newlines will be stripped out.
大胆强调我的。
改为使用 --data-binary
选项:
--data-binary <data>
(HTTP) This posts data exactly as specified with no extra processing whatsoever.
If you start the data with the letter @
, the rest should be a filename. Data is posted in a similar manner as --data-ascii
does, except that newlines and carriage returns are preserved and conversions are never done.
在那种情况下,您可能想要包含一个Content-Type
header;当然,如果您关心 header.
,这取决于您的处理程序
我正在 Google App Engine(不使用端点)上构建一个 REST API,允许用户上传 CSV 或 tab-delimited 文件并搜索可能的重复项。由于它是一个 API,我不能使用 <form>
或 BlobStore 的 upload_url
。我也不能指望有一个 Web 客户端会调用它 API。相反,理想情况下,用户将在请求的 body
中发送文件。
我的问题是,当我尝试读取 tab-delimited 文件的内容时,我发现所有换行符都已被删除,因此无法将内容拆分成行。
如果我直接在 Python 解释器上检查文件的内容,我看到那里有制表符和换行符(输出在示例中被截断)
>>> with open('./data/occ_sample.txt') as o:
... o.read()
...
'id\ttype\tmodified\tlanguage\trights\n123456\tPhysicalObject\t2015-11-11 11:50:59.0\ten\thttp://creativecommons.org/licenses/by-nc/3.0\n...'
RequestHandler
记录请求的内容 body:
import logging
class ReportApi(webapp2.RequestHandler):
def post(self):
logging.info(self.request.body)
...
所以当我通过 curl
dev_appserver
中调用 API 运行
curl -X POST -d @data/occ_sample.txt http://localhost:8080/api/v0/report
这显示在日志中:
id type modified language rights123456 PhysicalObject 2015-11-11 11:50:59.0 en http://creativecommons.org/licenses/by-nc/3.0
如您所见,headers 的最后一个值和第一个记录(分别为 rights
和 123456
)之间没有任何内容,最后一个值也是如此每条记录和下一条记录的第一个。
我是不是遗漏了什么明显的东西?我尝试用 self.request.body
、self.request.body_file
和 self.request.POST
加载数据,none 似乎有效。我还尝试在请求 headers 中应用 Content-Type
值 text/csv
、text/plain
、application/csv
,但没有成功。我应该添加不同的 Content-Type
吗?
您使用了错误的 curl
command-line 选项来发送您的文件数据,这个选项 正在删除换行符。
-d
选项 解析您的数据 并发送一个 application/x-www-form-urlencoded
请求,它 去除换行符 .来自 curl
manpage:
-d, --data <data>
[...]
If you start the data with the letter
@
, the rest should be a file name to read the data from, or-
if you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a file named'foobar'
would thus be done with--data @foobar
. When--data
is told to read from a file like that, carriage returns and newlines will be stripped out.
大胆强调我的。
改为使用 --data-binary
选项:
--data-binary <data>
(HTTP) This posts data exactly as specified with no extra processing whatsoever.
If you start the data with the letter
@
, the rest should be a filename. Data is posted in a similar manner as--data-ascii
does, except that newlines and carriage returns are preserved and conversions are never done.
在那种情况下,您可能想要包含一个Content-Type
header;当然,如果您关心 header.