【发布时间】:2019-08-15 17:49:55
【问题描述】:
这是我的 FileUploadView 类,用于处理上传文件的 POST 请求。我期待的文件是 XML 文件,我在其中使用 ElementTree 在 fileHandler() 中解析它。但是,当使用 Postman 通过 using ('form-data') 发送文件时,我意识到它正在将某种类型的标题附加到我上传的文件中,这反过来又导致 tree parse() 出现语法错误,因为它读取非 XML 格式的内容。
我尝试使用 HTTPie 发送文件,没有问题,XML Parser 正确解析它并将数据输入到预期的对象中。
然后我尝试用 Django 做一些测试用例,并尝试测试文件上传。由于再次将标头附加到文件,导致解析器再次出现语法错误。
class UploadTest(APITestCase):
def test_file_upload(self):
c = Client()
with open("/Users/Ren/Desktop/Capstone/Backend/projectB/VMA/testing/Test.xml") as fp:
c.post('/upload/TestXML.xml', {'filename' : 'Test.xml', 'attachment': fp})
我的问题是:是什么导致该标题弹出/添加到上传的文件中。我猜这与我如何通过 Postman 和与 HTTPie 不同的 Django TestCase 发送 post 请求有关
view.py
class FileUploadView(APIView):
parser_classes = (FileUploadParser,)
def post(self, request, filename, format=None):
print(request.FILES)
file_obj = request.FILES['file']
fileHandler(file_obj)
return Response(status=204)
FileReader.py
def fileHandler(file):
filepath = file.temporary_file_path()
print(file.read())
tree = ET.parse(filepath)
root = tree.getroot()
调用file.read()时的XML文件和输出
XML I need to read in (Expected Output):
<site host="192.168.212.4" name="http://192.168.212.4" port="80" ssl="false"><alerts><alertitem>\n <pluginid>10021</pluginid>\n <alert>X-Content-Type-Options header missing</alert>\n <riskcode>1</riskcode>\n <reliability>2</reliability>\n <riskdesc>Low (Warning)</riskdesc>\n <desc>The Anti-MIME-Sniffing header X-Content-Type-Options was not set to \'nosniff\'.\n\tThis allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type.\n\tCurrent (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.\n\t</desc>\n <uri>http://192.168.212.4/</uri>\n <param/>\n <attack/>\n <otherinfo/>\n <solution>Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to \'nosniff\' for all web pages.\n\tIf possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.\n\t</solution>\n <reference>\n\t</reference>\n</alertitem>
The Output when running request.FILES['file'].read() --- Current Output
b'----------------------------507481440966899800347275\r\nContent-Disposition: form-data; name=""; filename="sampleXML.xml"\r\nContent-Type: application/xml\r\n\r\n<site host="192.168.212.4" name="http://192.168.212.4" port="80" ssl="false"><alerts><alertitem>\n <pluginid>10021</pluginid>\n <alert>X-Content-Type-Options header missing</alert>\n <riskcode>1</riskcode>\n <reliability>2</reliability>\n <riskdesc>Low (Warning)</riskdesc>\n <desc>The Anti-MIME-Sniffing header X-Content-Type-Options was not set to \'nosniff\'.\n\tThis allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type.\n\tCurrent (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.\n\t</desc>\n <uri>http://192.168.212.4/</uri>\n <param/>\n <attack/>\n <otherinfo/>\n <solution>Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to \'nosniff\' for all web pages.\n\tIf possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.\n\t</solution>\n <reference>\n\t</reference>\n</alertitem>\n\n \r\n----------------------------507481440966899800347275--\r\n'
包含不必要的:b'----------------507481440966899800347275\r\nContent-Disposition: form-data;名称=""; filename="sampleXML.xml"\r\nContent-Type: application/xml\r\n\r\n
【问题讨论】:
-
该代码是如何发送到 API 的?显示您的前端代码。
-
您是如何发布文件的?这是将文件附加到 POST 请求正文的标准方法,但如果您的 POST HTTP 标头包含正确的内容类型,Django 应该删除这部分。
-
这是“Content-Type”标头的样子:“multipart/form-data;boundary=------------------ ---------507481440966899800347275" 以便 Django 可以了解文件的开始位置。
-
我通过邮递员发送 HTTP POST 请求,我仍然不熟悉邮递员,所以这可能是问题所在。使用 Postman,我正在发送附有 XML 文件的表单数据,仅此而已。临时标头发送的内容类型是“multipart/form-data'boundary=------------------------”这是问题的原因吗?因为它是一个临时标题?
-
我尝试使用 HTTPie 发送文件。它按预期完美运行。所以现在我倾向于邮递员成为问题 - 它出于某种原因将标题详细信息写入文件,这导致 XML Reader 出现问题
标签: python django django-rest-framework