当前位置:  开发笔记 > 编程语言 > 正文

MultiPartParserError: - 边界无效

如何解决《MultiPartParserError:-边界无效》经验,为你挑选了1个好方法。

我试图使用Python请求模块将一些数据和文件发送到我的django rest应用程序但是得到以下错误.

    raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)
MultiPartParserError: Invalid boundary in multipart: None

码:-

import requests
payload={'admins':[
                    {'first_name':'john'
                    ,'last_name':'white'
                    ,'job_title':'CEO'
                    ,'email':'test1@gmail.com'
                    },
                    {'first_name':'lisa'
                    ,'last_name':'markel'
                    ,'job_title':'CEO'
                    ,'email':'test2@gmail.com'
                    }
                    ],
        'company-detail':{'description':'We are a renowned engineering company'
                    ,'size':'1-10'
                    ,'industry':'Engineering'
                    ,'url':'http://try.com'
                    ,'logo':''
                    ,'addr1':'1280 wick ter'
                    ,'addr2':'1600'
                    ,'city':'rkville'
                    ,'state':'md'
                    ,'zip_cd':'12000'
                    ,'phone_number_1':'408-393-254'
                    ,'phone_number_2':'408-393-221'
                    ,'company_name':'GOOGLE'}
        }
files = {'upload_file':open('./test.py','rb')}
import json
headers = {'content-type' : 'application/json'}      
headers = {'content-type' : 'multipart/form-data'}      

#r = requests.post('http://127.0.0.1:8080/api/create-company-profile/',data=json.dumps(payload),headers=headers,files=files)
r = requests.post('http://127.0.0.1:8080/api/create-company-profile/',data=payload,headers=headers,files=files)
print r.status_code
print r.text

Django代码: -

class CompanyCreateApiView(CreateAPIView):
    parser_classes = (MultiPartParser, FormParser,)
    def post(self, request, *args, **kwargs):
        print 'request ==', request.data

7stud.. 8

好的,我忘记了你的标题.根据规格:

Content-Type   = "Content-Type" ":" media-type

MIME提供了许多"多部分"类型 - 单个消息体内的一个或多个实体的封装.所有多部分类型共享一个通用语法,...并且必须包含边界参数作为媒体类型值的一部分.

以下是包含multipart/form-data的请求:

POST /myapp/company/ HTTP/1.1
Host: localhost:8000
Content-Length: 265
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.9.0
Connection: keep-alive
Content-Type: multipart/form-data; boundary=63c5979328c44e2c869349443a94200e   

--63c5979328c44e2c869349443a94200e
Content-Disposition: form-data; name="hello"

world
--63c5979328c44e2c869349443a94200e
Content-Disposition: form-data; name="mydata"; filename="data.txt"

line 1
line 2
line 3
line 4

--63c5979328c44e2c869349443a94200e--

查看数据部分如何按边界分隔:

--63c5979328c44e2c869349443a94200e--

我们的想法是将某些东西用于不太可能出现在数据中的边界.请注意,边界包含在Content-Type请求的标头中.

该请求由此代码生成:

import requests

myfile = {'mydata': open('data.txt','rb')}

r = requests.post(url, 
        #headers = myheaders
        data = {'hello': 'world'}, 
        files = myfile
) 

看起来您正在仔细关注django-rest-framework 文档中的以下注释:

注意:在开发客户端应用程序时,请始终记住确保在HTTP请求中发送数据时设置Content-Type标头.

如果您没有设置内容类型,大多数客户端将默认使用'application/x-www-form-urlencoded',这可能不是您想要的.

但是当你使用时requests,如果你Content-Type自己指定标题,那么requests假设你知道你正在做什么,并且它不会Content-TypeContent-Type它本来提供的标题覆盖你的标题.

您没有在Content-Type标题中提供边界- 根据需要.你怎么能?您没有组装请求的主体并创建边界来分隔各种数据,因此您无法知道边界是什么.

django-rest-framework笔记说您应该Content-Type在请求中包含标题时,这意味着:

您或用于创建请求的任何程序都需要包含 Content-Type标题.

所以@AChampion在评论中是完全正确的:在所有文档广告之后requests提供:Content-Type headerrequests

请求从Python HTTP/1.1中获取所有工作

requests是这样的:如果你提供一个files关键字arg,那么请求使用Content-Type标题,multipart/form-data并在标题中指定一个边界; 然后requests使用边界组装请求的主体.如果你提供了一个data关键字参数,然后请求使用Content-Typeapplication/x-www-form-urlencoded,这只不过是组装的所有键和值的字典成这种格式:

x=10&y=20

无需边界.

而且,如果你同时提供files关键字ARG和data关键字ARG,然后请求使用Content-Typemultipart/form-data.



1> 7stud..:

好的,我忘记了你的标题.根据规格:

Content-Type   = "Content-Type" ":" media-type

MIME提供了许多"多部分"类型 - 单个消息体内的一个或多个实体的封装.所有多部分类型共享一个通用语法,...并且必须包含边界参数作为媒体类型值的一部分.

以下是包含multipart/form-data的请求:

POST /myapp/company/ HTTP/1.1
Host: localhost:8000
Content-Length: 265
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.9.0
Connection: keep-alive
Content-Type: multipart/form-data; boundary=63c5979328c44e2c869349443a94200e   

--63c5979328c44e2c869349443a94200e
Content-Disposition: form-data; name="hello"

world
--63c5979328c44e2c869349443a94200e
Content-Disposition: form-data; name="mydata"; filename="data.txt"

line 1
line 2
line 3
line 4

--63c5979328c44e2c869349443a94200e--

查看数据部分如何按边界分隔:

--63c5979328c44e2c869349443a94200e--

我们的想法是将某些东西用于不太可能出现在数据中的边界.请注意,边界包含在Content-Type请求的标头中.

该请求由此代码生成:

import requests

myfile = {'mydata': open('data.txt','rb')}

r = requests.post(url, 
        #headers = myheaders
        data = {'hello': 'world'}, 
        files = myfile
) 

看起来您正在仔细关注django-rest-framework 文档中的以下注释:

注意:在开发客户端应用程序时,请始终记住确保在HTTP请求中发送数据时设置Content-Type标头.

如果您没有设置内容类型,大多数客户端将默认使用'application/x-www-form-urlencoded',这可能不是您想要的.

但是当你使用时requests,如果你Content-Type自己指定标题,那么requests假设你知道你正在做什么,并且它不会Content-TypeContent-Type它本来提供的标题覆盖你的标题.

您没有在Content-Type标题中提供边界- 根据需要.你怎么能?您没有组装请求的主体并创建边界来分隔各种数据,因此您无法知道边界是什么.

django-rest-framework笔记说您应该Content-Type在请求中包含标题时,这意味着:

您或用于创建请求的任何程序都需要包含 Content-Type标题.

所以@AChampion在评论中是完全正确的:在所有文档广告之后requests提供:Content-Type headerrequests

请求从Python HTTP/1.1中获取所有工作

requests是这样的:如果你提供一个files关键字arg,那么请求使用Content-Type标题,multipart/form-data并在标题中指定一个边界; 然后requests使用边界组装请求的主体.如果你提供了一个data关键字参数,然后请求使用Content-Typeapplication/x-www-form-urlencoded,这只不过是组装的所有键和值的字典成这种格式:

x=10&y=20

无需边界.

而且,如果你同时提供files关键字ARG和data关键字ARG,然后请求使用Content-Typemultipart/form-data.

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有