在 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 的最后一个值和第一个记录(分别为 rights123456)之间没有任何内容,最后一个值也是如此每条记录和下一条记录的第一个。

我是不是遗漏了什么明显的东西?我尝试用 self.request.bodyself.request.body_fileself.request.POST 加载数据,none 似乎有效。我还尝试在请求 headers 中应用 Content-Typetext/csvtext/plainapplication/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.

,这取决于您的处理程序