Flask文件上传无法获取表单数据

Dou*_*oug 4 python flask angular

角度 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);
    }
);
Run Code Online (Sandbox Code Playgroud)

...调用提供商...

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);
}
Run Code Online (Sandbox Code Playgroud)

在 Flask API 端我有这个:

@app.route('/api/member/uploadFile', methods=['POST'])
@auth.login_required
def uploadFile(): 
    print request.form.get('key1')
    return "ok"
Run Code Online (Sandbox Code Playgroud)

运行此命令会在 Flask 开发服务器终端中输出“None”。

如果我这样做,print request.get_data()我会看到所有的帖子数据(包括疯狂的图像数据)。

在 Chrome 中,请求如下所示:

在此输入图像描述

知道我做错了什么以及如何从 Flask 中获取数据吗?

谢谢!

Mar*_*ers 8

你做错了两件事:

  • 您将Content-Type标题设置为null,因此它留空。现在 Angular 无法告诉服务器如何拆分请求的不同部分multipart/form

  • 您没有访问服务器端的正确字段。

您根本应该设置标头,因此请删除该调用。然后,Angular 4会为您设置标头,并将边界值(请求正文中的字段之间的字符串)包含在该标头中。Content-Typeheaders.set('Content-Type', null)multipart/form-data

您的 Flask 代码正在尝试访问不存在的字段。您的前端代码发布两个字段:

formModel.set('fileName', this.fileName);
formModel.set('fileData', this.form.get('fileData').value);
Run Code Online (Sandbox Code Playgroud)

您的屏幕截图证实了这一点,fileName并且fileData零件确实已发布。但是你的 Flask 代码尝试访问key1

print request.form.get('key1')
Run Code Online (Sandbox Code Playgroud)

没有这样的键,因此该.get()方法返回默认值 , None

对于文件上传,你确实想使用request.files属性requests.form请参阅该属性和属性的文档:

form:A带有来自或请求的MultiDict已解析表单数据。请记住,文件上传不会在此处结束,而是在属性中结束。POSTPUTfiles

[...]

files:A,MultiDict其中文件作为POSTPUT请求的一部分上传。每个文件都存储为FileStorage对象。它的行为基本上类似于 Python 中的标准文件对象,不同之处在于它还有一个save()可以将文件存储在文件系统上的函数。

因此使用request.form['fileName']request.files['fileData']来访问这两个字段。

另请参阅上传文件模式文档

附注:您不应该设置标题Accept。标Accept头供客户端(例如您的浏览器)告诉服务器什么样的响应是可以接受的。Accept: multipart/form告诉服务器您希望它做出响应multipart/form它没有提及请求本身的内容。如果您从这篇博文的评论中获得了示例(Google 的热门搜索“Angular 4 表单数据上传”),那么该评论者已经用无效代码误导了您。我在那里添加了一条评论,至少可以帮助未来的访问者避免该错误。