角度4 烧瓶1.0.2
大家好
我试图通过填充一个新的FormData()对象并将其发布来从Angular上传文件。它似乎可以正常发布,但是我无法从Flask中获取该帖子中的值。
我通过按钮点击事件来调用它:
UploadFile() : void{
let formModel = new FormData()
formModel.set('fileName', this.fileName);
formModel.set('fileData', this.form.get('fileData').value);
this.filesProvider.UploadFile(formModel)
.subscribe(res => {
this.UploadFileProcessed(res, true);
}
, (err) => {
this.UploadFileProcessed(err, false);
}
);
...呼叫提供者...
UploadFile(formData: FormData) : Observable<Response> {
let headers = new Headers();
headers.set('Content-Type', null);
headers.set('Accept', "multipart/form-data");
headers.set('Authorization', 'Basic ' + btoa(access_token + ":"));
let requestOptions = new RequestOptions({ headers: headers })
return this.http
.post(this.globalVarsProvider.apiUrl + "member/uploadFile", formData, requestOptions)
.map((response: Response) => response);
}
在Flask API端,我有这个:
@app.route('/api/member/uploadFile', methods=['POST'])
@auth.login_required
def uploadFile():
print request.form.get('key1')
return "ok"
在Flask dev服务器终端中运行此命令将输出“ None”。
如果我做print request.get_data()
,我会看到所有的帖子数据(包括疯狂的图片数据)。
在Chrome中,请求如下所示:
请问我在做什么错,以及如何从Flask中获取数据?
谢谢!
答案 0 :(得分:2)
您做错了两件事:
您将Content-Type
标头设置为null
,因此将其保留为空。现在Angular无法告诉服务器如何拆分multipart/form
请求的不同部分。
您没有在服务器端访问正确的字段。
您完全不应该设置Content-Type
标头,因此请删除headers.set('Content-Type', null)
调用。角度4然后从sets the header for you到multipart/form-data
,并将在该标头中包含边界值(请求主体中字段之间的字符串)。
您的Flask代码正在尝试访问不存在的字段。您的前端代码发布了两个字段:
formModel.set('fileName', this.fileName);
formModel.set('fileData', this.form.get('fileData').value);
和您的屏幕快照确认确实发布了fileName
和fileData
部分。但是您的Flask代码尝试访问key1
:
print request.form.get('key1')
没有此类键,因此.get()
方法将返回默认值None
。
对于文件上传,您确实要使用request.files
attribute;请参阅该属性和requests.form
attribute的文档:
form
:具有MultiDict
或POST
请求中解析出的表单数据的PUT
。请记住,文件上传不会在这里结束,而是在files
属性中。[...]
files
:一个MultiDict
,其中包含作为POST
或PUT
请求的一部分上传的文件。每个文件都存储为FileStorage
对象。它的行为基本上就像您从Python知道的标准文件对象一样,不同之处在于它还有一个save()
函数可以将文件存储在文件系统中。
因此,使用request.form['fileName']
和request.files['fileData']
访问这两个字段。
另请参阅Uploading Files pattern documentation。
作为旁注:您不应设置Accept
标头。 Accept
标头用于客户端(例如您的浏览器)告诉服务器可接受哪种响应。 Accept: multipart/form
告诉服务器您希望它以multipart/form
响应来响应。它没有说明请求本身的内容。如果您的示例来自对this blog post (a top Google hit for "angular 4 form-data upload")的注释,则该注释者会以无效代码误导您。我在此处添加了评论,至少可以帮助将来的访问者避免该错误。