简体   繁体   English

如何将文件从Angular 2上传到Django服务器? (enctype =“ multipart / form-data”)

[英]How to upload a file from Angular 2 to Django Server? (enctype=“multipart/form-data”)

I have seen multiple questions on stackoverflow similar to this but I have not been able to solve the following issue. 我已经在stackoverflow上看到了多个与此类似的问题,但是我无法解决以下问题。

I can successfully upload a file using this html form: 我可以使用以下html格式成功上传文件:

<form method="POST" action="//127.0.0.1:8000/upload" enctype="multipart/form-data"> 
    <input type="file" name="myfile" required>
    <button type="submit">Upload</button>
</form>

and here is how the file is handled on the server side: 这是在服务器端处理文件的方式:

views.py views.py

def upload_file(request):
    f = request.FILES['myfile']
    with open('media/name.jpg', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    return HttpResponse('Done')

Everything works perfectly up to this point. 到目前为止,一切都完美。 The file gets uploaded and saved as name.jpg on disk. 该文件被上传并保存为name.jpg在磁盘上。 Now, I would like to replace the html above to post the file without a url redirect (using angular 2 http). 现在,我想替换上面的html来发布文件而不进行URL重定向(使用angular 2 http)。 Following this answer , here is my current implementation: 此答案之后 ,这是我当前的实现:

file-upload.component.ts file-upload.component.ts

import { Component, ElementRef } from '@angular/core';
import {Http, Headers, RequestOptions, Response} from '@angular/http';

@Component({
    selector: 'file-upload',
    template: '<input type="file" name="myfile">' 
})
export class FileUploadComponent {
    constructor(private http: Http, private el: ElementRef) {}
upload() {
    var headers = new Headers();
    headers.append('Content-Type','multipart/form-data');
    let inputEl = this.el.nativeElement.firstElementChild;
    if (inputEl.files.length > 0) {
        let file:FileList = inputEl.files[0];
        this.http
            .post('http://127.0.0.1:8000/upload', file, {headers: headers})
            .subscribe();
    }
}

and call it like this: 并这样称呼它:

<file-upload #myfile (change)="myfile.upload()"></file-upload>

I get a 400 bad request error saying (Unable to parse request body), and I think it happens at this line: 我收到一个400错误的请求错误消息(无法解析请求正文),并且我认为它发生在这一行:

f = request.FILES['myfile']

since request.FILES requires enctype="multipart/form-data", my first hunch is that I am not passing multipart/form-data correctly. 由于request.FILES需要enctype =“ multipart / form-data”,所以我的第一个直觉是我没有正确传递multipart / form-data。

A lot of older discussions suggest the use of XMLHttpRequest since at the time upload file with http was not supported apparently. 许多较早的讨论都建议使用XMLHttpRequest,因为当时显然不支持使用http上传文件。 I tried that as well and still get the same error. 我也尝试过,但仍然遇到相同的错误。

Any suggestions would be appreciated. 任何建议,将不胜感激。

I think your problem is: 我认为您的问题是:

enctype="multipart/form-data"

If you're using a form service sometimes the HTML form tags cause problems. 如果您使用的是表单服务,则有时HTML表单标签会引起问题。 I would try it just using: 我会尝试使用:

<input type="file" name="myfile" required>
    <button type="submit">Upload</button>

I would definitely still use some type of form, just thought this would be quick to debug why it is failing. 我肯定仍会使用某种形式的表单,只是认为这样做可以快速调试为什么失败。 I would use the angular 2 form library. 我将使用angular 2表单库。

Also, here is a multipart upload service that I use: 另外,这是我使用的分段上传服务:

import { Injectable } from '@angular/core';


@Injectable()
export class UploadService {

    public makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
        return new Promise((resolve, reject) => {            
            let formData: any = new FormData();
            let xhr = new XMLHttpRequest();
            for(let i =0; i < files.length; i++) {
                formData.append('file', files[i], files[i].name);
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        resolve(xhr.response);                        
                    } else {
                        reject(xhr.response);
                    }
                }
            };
            let bearer = 'Bearer ' + localStorage.getItem('currentUser');               
            xhr.open('POST', url, true);
            xhr.setRequestHeader('Authorization', bearer);
            xhr.send(formData);
        });
    }
}

you only need the auth if you're using JWT authentication. 仅在使用JWT身份验证时才需要auth。 If you are not, you want to take out these lines: 如果不是,则要删除以下行:

let bearer = 'Bearer ' + localStorage.getItem('currentUser'); 
xhr.setRequestHeader('Authorization', bearer);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Django中的enctype =“ multipart / form-data”表单验证失败 - form validation fail in django with enctype=“multipart/form-data” Django enctype="multipart/form-data" 未设置 POST 数据 - Django enctype="multipart/form-data" not setting POST data enctype='multipart/form-data' 不是在 django 中存储图像吗? - enctype='multipart/form-data' is not storing images in django? Django Tastypie 反序列化 Multipart/Form-Data 以上传文件 - Django Tastypie Deserializing Multipart/Form-Data To Upload File Django:即使设置了enctype = multipart / form-data,文件也没有在请求中传递? - Django : Files not passed in the request even after setting enctype=multipart/form-data? 如何从角度发布多部分/表单数据到Django REST API - How to post multipart/form-data from angular to Django REST API 是否可以在后端为表单设置enctype =“ multipart / form-data”? - Is it possible to set the enctype=“multipart/form-data” for a form in the backend? 为什么不总是使用 enctype=&quot;multipart/form-data&quot;? - Why not use enctype=“multipart/form-data” always? Django 无法使用 multipart/form-data 上传图片 - Django unable to upload image using multipart/form-data Django REST Framework 文件上传导致“不支持的媒体类型‘multipart/form-data’”错误 - Django REST Framework file upload causing an “Unsupported media type 'multipart/form-data'” error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM