Açısal Dosya Yükleme?


Yanıtlar:


375

Açısal 2, dosyaları yüklemek için iyi bir destek sağlar. Üçüncü taraf kitaplığı gerekmez.

<input type="file" (change)="fileChange($event)" placeholder="Upload file" accept=".pdf,.doc,.docx">
fileChange(event) {
    let fileList: FileList = event.target.files;
    if(fileList.length > 0) {
        let file: File = fileList[0];
        let formData:FormData = new FormData();
        formData.append('uploadFile', file, file.name);
        let headers = new Headers();
        /** In Angular 5, including the header Content-Type can invalidate your request */
        headers.append('Content-Type', 'multipart/form-data');
        headers.append('Accept', 'application/json');
        let options = new RequestOptions({ headers: headers });
        this.http.post(`${this.apiEndPoint}`, formData, options)
            .map(res => res.json())
            .catch(error => Observable.throw(error))
            .subscribe(
                data => console.log('success'),
                error => console.log(error)
            )
    }
}

@ açısal / çekirdek ":" ~ 2.0.0 "ve @ açısal / http:" ~ 2.0.0 "kullanarak


5
en azından benim durumumda çalışmıyor. sailsJs server boş dosya dizisi / nesne alıyor
Kaleem Ullah

20
Benim için çalıştı - bu satırda çalışmak zorunda kaldım- headers.append('enctype', 'multipart/form-data');('Content-Type' yerine 'enctype' kullandım). Belki de sunucu tarafı koda bağlıdır. (yani api)
Ariful Islam

29
Açısal ekip konuyla ilgili bazı belgeler yazabilirse, dokümanlarında bu konuda tek bir satır bulamıyorum. Bu kod örneği güncel değil ve v4 + ile çalışmaz.
Rob B

10
Bazı uygulama sunucuları için içerik türünün ayarlanması reddedilecektir. Boş bırakmanız gerekir: let headers = new Headers (); Tarayıcı her şeyi sizin için halledecektir.
PeterS

6
Başlıkları ayarlamak zorunda olmadığımı fark edene kadar LMFAO bu saçmalıklarla 20 dakika mücadele etti. Net webapi ile açısal 4.xx kullanan diğerlerine dikkat edin, başlıkları ayarlamaya çalışmayın! @PeterS
Jota.Toledo

76

Yukarıdaki cevaplardan bunu Angular 5.x ile oluşturuyorum

uploadFile(url, file).subscribe()Bir yüklemeyi tetiklemek için arayın

import { Injectable } from '@angular/core';
import {HttpClient, HttpParams, HttpRequest, HttpEvent} from '@angular/common/http';
import {Observable} from "rxjs";

@Injectable()
export class UploadService {

  constructor(private http: HttpClient) { }

  // file from event.target.files[0]
  uploadFile(url: string, file: File): Observable<HttpEvent<any>> {

    let formData = new FormData();
    formData.append('upload', file);

    let params = new HttpParams();

    const options = {
      params: params,
      reportProgress: true,
    };

    const req = new HttpRequest('POST', url, formData, options);
    return this.http.request(req);
  }
}

Bileşeninizde böyle kullanın

  // At the drag drop area
  // (drop)="onDropFile($event)"
  onDropFile(event: DragEvent) {
    event.preventDefault();
    this.uploadFile(event.dataTransfer.files);
  }

  // At the drag drop area
  // (dragover)="onDragOverFile($event)"
  onDragOverFile(event) {
    event.stopPropagation();
    event.preventDefault();
  }

  // At the file input element
  // (change)="selectFile($event)"
  selectFile(event) {
    this.uploadFile(event.target.files);
  }

  uploadFile(files: FileList) {
    if (files.length == 0) {
      console.log("No file selected!");
      return

    }
    let file: File = files[0];

    this.upload.uploadFile(this.appCfg.baseUrl + "/api/flash/upload", file)
      .subscribe(
        event => {
          if (event.type == HttpEventType.UploadProgress) {
            const percentDone = Math.round(100 * event.loaded / event.total);
            console.log(`File is ${percentDone}% loaded.`);
          } else if (event instanceof HttpResponse) {
            console.log('File is completely loaded!');
          }
        },
        (err) => {
          console.log("Upload Error:", err);
        }, () => {
          console.log("Upload done");
        }
      )
  }

6
Angular6 ile iyi çalışır. Teşekkür ederim. Ve içe aktarmak için bu kütüphanelere ihtiyacınız var. '@ angular / common / http' den {HttpClient, HttpParams, HttpRequest, HttpEvent, HttpEventType, HttpResponse} 'i içe aktarın;
Bharathiraja

1
benim durumumda yetkilendirme taşıyıcısını kullanıyordum ve bu ekstra kodu ekledimlet params = new HttpParams(); let headers = new HttpHeaders({ 'Authorization': 'Bearer ' + localStorage.getItem('accessToken'), }); const options = { headers: headers, params: params, reportProgress: true, };
Ciprian Dragoe

İşlevin geri dönüş türünü sağlamak için tür çıkarımı kullanma konusunda sorun yaşıyorsanız , içe aktarma işleminin tamamen kaldırılabileceğini Observableve HttpEventatlanabileceğini belirtmek gerekir uploadFile()! this.http.request()zaten bir tür döndürür Observable<HttpEvent<{}>>, bu nedenle istek çağrısı genel bir tür verirseniz (yani this.http.request<any>(), tüm işlev sadece doğru türlerle çalışır
wosevision

2
Html kısmı böyle gider input type="file" (change)="addFiles($event)" style="display: none" #file multiple> <button mat-raised-button color="primary" (click)="selectFile($event)">Upload File </button>
Shantam Mittal

22

@Eswar'a teşekkürler. Bu kod benim için mükemmel çalıştı. Çözüme belirli şeyler eklemek istiyorum:

Hata alıyordum: java.io.IOException: RESTEASY007550: Unable to get boundary for multipart

Bu hatayı çözmek için, "İçerik Tipi" "çoklu bölüm / form verileri" ni kaldırmalısınız. Sorunumu çözdü.


5
+1. İçerik Türü'nü kaldırırsanız, doğru bir şekilde oluşturulur. Ör: multipart/form-data; boundary=---------------------------186035562730765173675680113. Ayrıca bkz. Stackoverflow.com/a/29697774/1475331 ve github.com/angular/angular/issues/11819 .
turdus-merula

1
java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found"Sizinkine benzer bu hatayı alıyorum , ancak Content-Typebaşlığı kaldırdığımda arka uçtan bir 404 alıyorum. Yay ve Açısal 2 kullanıyoruz. Herhangi bir yardım takdir.
Helen

Bu sadece cevabına bir yorum olmalı, değil mi?
MMalke

19

Kod örneği biraz modası geçmiş olduğundan, daha yeni bir yaklaşım paylaşacağımı düşündüm, Açısal 4.3 ve yeni (er) HttpClient API, @ angular / common / http

export class FileUpload {

@ViewChild('selectedFile') selectedFileEl;

uploadFile() {
let params = new HttpParams();

let formData = new FormData();
formData.append('upload', this.selectedFileEl.nativeElement.files[0])

const options = {
    headers: new HttpHeaders().set('Authorization', this.loopBackAuth.accessTokenId),
    params: params,
    reportProgress: true,
    withCredentials: true,
}

this.http.post('http://localhost:3000/api/FileUploads/fileupload', formData, options)
.subscribe(
    data => {
        console.log("Subscribe data", data);
    },
    (err: HttpErrorResponse) => {
        console.log(err.message, JSON.parse(err.error).error.message);
    }
)
.add(() => this.uploadBtn.nativeElement.disabled = false);//teardown
}

1
bunun için html var mı? Bu HttpParams kullanıyor gibi. Sadece bir yerde tam bir çalışma örneğiniz olup olmadığını merak ediyorum. Teşekkürler
Maddy

Bu şekilde bir dizi olarak birden çok dosyayı nasıl birlikte yükleyebilirim? form veri nesnesine nasıl eklenmelidir?
SSR

çok bölümlü form verilerine bir göz atın webdavsystem.com/javaserver/doc/resumable_upload/multipart_post
jsaddwater

15

Angular 2+ sürümünde, İçerik Türü'nü boş bırakmak çok önemlidir . 'İçerik Türü'nü' çok parçalı / form verileri 'olarak ayarlarsanız yükleme çalışmaz!

upload.component.html

<input type="file" (change)="fileChange($event)" name="file" />

upload.component.ts

export class UploadComponent implements OnInit {
    constructor(public http: Http) {}

    fileChange(event): void {
        const fileList: FileList = event.target.files;
        if (fileList.length > 0) {
            const file = fileList[0];

            const formData = new FormData();
            formData.append('file', file, file.name);

            const headers = new Headers();
            // It is very important to leave the Content-Type empty
            // do not use headers.append('Content-Type', 'multipart/form-data');
            headers.append('Authorization', 'Bearer ' + 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9....');
            const options = new RequestOptions({headers: headers});

            this.http.post('https://api.mysite.com/uploadfile', formData, options)
                 .map(res => res.json())
                 .catch(error => Observable.throw(error))
                 .subscribe(
                     data => console.log('success'),
                     error => console.log(error)
                 );
        }
    }
}


7

Bu basit çözüm benim için çalıştı: file-upload.component.html

<div>
  <input type="file" #fileInput placeholder="Upload file..." />
  <button type="button" (click)="upload()">Upload</button>
</div>

Ve sonra doğrudan XMLHttpRequest ile bileşene yükleme yapın .

import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css']
})
export class FileUploadComponent implements OnInit {

  @ViewChild('fileInput') fileInput;

  constructor() { }

  ngOnInit() {
  }

  private upload() {
    const fileBrowser = this.fileInput.nativeElement;
    if (fileBrowser.files && fileBrowser.files[0]) {
      const formData = new FormData();
      formData.append('files', fileBrowser.files[0]);
      const xhr = new XMLHttpRequest();
      xhr.open('POST', '/api/Data/UploadFiles', true);
      xhr.onload = function () {
        if (this['status'] === 200) {
            const responseText = this['responseText'];
            const files = JSON.parse(responseText);
            //todo: emit event
        } else {
          //todo: error handling
        }
      };
      xhr.send(formData);
    }
  }

}

Dotnet çekirdeği kullanıyorsanız, parametre adı, alan adıyla eşleşmelidir. bu durumda dosyalar:

[HttpPost("[action]")]
public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files)
{
  return await _binaryService.UploadFilesAsync(files);
}

Bu cevap http://blog.teamtreehouse.com/uploading-files-ajax

Düzenle : Yükledikten sonra, kullanıcının yeni bir dosya seçebilmesi için dosya yüklemesini temizlemeniz gerekir. Ve XMLHttpRequest kullanmak yerine, fetch kullanmak daha iyidir:

private addFileInput() {
    const fileInputParentNative = this.fileInputParent.nativeElement;
    const oldFileInput = fileInputParentNative.querySelector('input');
    const newFileInput = document.createElement('input');
    newFileInput.type = 'file';
    newFileInput.multiple = true;
    newFileInput.name = 'fileInput';
    const uploadfiles = this.uploadFiles.bind(this);
    newFileInput.onchange = uploadfiles;
    oldFileInput.parentNode.replaceChild(newFileInput, oldFileInput);
  }

  private uploadFiles() {
    this.onUploadStarted.emit();
    const fileInputParentNative = this.fileInputParent.nativeElement;
    const fileInput = fileInputParentNative.querySelector('input');
    if (fileInput.files && fileInput.files.length > 0) {
      const formData = new FormData();
      for (let i = 0; i < fileInput.files.length; i++) {
        formData.append('files', fileInput.files[i]);
      }

      const onUploaded = this.onUploaded;
      const onError = this.onError;
      const addFileInput = this.addFileInput.bind(this);
      fetch('/api/Data/UploadFiles', {
        credentials: 'include',
        method: 'POST',
        body: formData,
      }).then((response: any) => {
        if (response.status !== 200) {
          const error = `An error occured. Status: ${response.status}`;
          throw new Error(error);
        }
        return response.json();
      }).then(files => {
        onUploaded.emit(files);
        addFileInput();
      }).catch((error) => {
        onError.emit(error);
      });
    }

https://github.com/yonexbat/cran/blob/master/cranangularclient/src/app/file-upload/file-upload.component.ts


3

Bu, ng2-dosya-upload ve ng2-dosya-upload OLMADAN nasıl dosya yükleneceği konusunda faydalı bir öğreticidir .

Benim için çok yardımcı oluyor.

Şu anda, öğretici birkaç hata içeriyor:

1- İstemci, sunucu ile aynı yükleme URL'sine sahip olmalıdır, bu nedenle app.component.tsdeğişiklik satırında

const URL = 'http://localhost:8000/api/upload';

için

const URL = 'http://localhost:3000';

Böylece de 'metin / html' olarak 2- Sunucu gönderme yanıtı, app.component.tsdeğişim

.post(URL, formData).map((res:Response) => res.json()).subscribe(
  //map the success function and alert the response
  (success) => {
    alert(success._body);
  },
  (error) => alert(error))

için

.post(URL, formData)  
.subscribe((success) => alert('success'), (error) => alert(error));

3

Form alanlarıyla resim yüklemek için

SaveFileWithData(article: ArticleModel,picture:File): Observable<ArticleModel> 
{

    let headers = new Headers();
    // headers.append('Content-Type', 'multipart/form-data');
    // headers.append('Accept', 'application/json');

let requestoptions = new RequestOptions({
  method: RequestMethod.Post,
  headers:headers
    });



let formData: FormData = new FormData();
if (picture != null || picture != undefined) {
  formData.append('files', picture, picture.name);
}
 formData.append("article",JSON.stringify(article));

return this.http.post("url",formData,requestoptions)
  .map((response: Response) => response.json() as ArticleModel);
} 

Benim durumumda C # .NET Web Api gerekli

// POST: api/Articles
[ResponseType(typeof(Article))]
public async Task<IHttpActionResult> PostArticle()
{
    Article article = null;
    try
    {

        HttpPostedFile postedFile = null;
        var httpRequest = HttpContext.Current.Request;

        if (httpRequest.Files.Count == 1)
        {
            postedFile = httpRequest.Files[0];
            var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
            postedFile.SaveAs(filePath);
        }
        var json = httpRequest.Form["article"];
         article = JsonConvert.DeserializeObject <Article>(json);

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        article.CreatedDate = DateTime.Now;
        article.CreatedBy = "Abbas";

        db.articles.Add(article);
        await db.SaveChangesAsync();
    }
    catch (Exception ex)
    {
        int a = 0;
    }
    return CreatedAtRoute("DefaultApi", new { id = article.Id }, article);
}

3

Bugün ng2-file-upload entegre edildi paketini açısal 6 uygulamama , oldukça basitti, lütfen aşağıdaki üst düzey kodu bulun.

ng2 dosya yükleme modülünü içe aktarma

app.module.ts

    import { FileUploadModule } from 'ng2-file-upload';

    ------
    ------
    imports:      [ FileUploadModule ],
    ------
    ------

Bileşen ts dosyası içe aktarma FileUploader

app.component.ts

    import { FileUploader, FileLikeObject } from 'ng2-file-upload';
    ------
    ------
    const URL = 'http://localhost:3000/fileupload/';
    ------
    ------

     public uploader: FileUploader = new FileUploader({
        url: URL,
        disableMultipart : false,
        autoUpload: true,
        method: 'post',
        itemAlias: 'attachment'

        });

      public onFileSelected(event: EventEmitter<File[]>) {
        const file: File = event[0];
        console.log(file);

      }
    ------
    ------

Bileşen HTML dosya etiketi ekle

app.component.html

 <input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" />

Çevrimiçi Çalışma stackblitz Bağlantısı: https://ng2-file-upload-example.stackblitz.io

Stackblitz Kodu örneği: https://stackblitz.com/edit/ng2-file-upload-example

Resmi dokümantasyon bağlantısı https://valor-software.com/ng2-file-upload/


1

optionsParametreyi ayarlamamaya çalışın

this.http.post(${this.apiEndPoint}, formData)

ve globalHeadersHttp fabrikanızda ayarı yapmadığınızdan emin olun .


1

En basit biçimde, aşağıdaki kod Açısal 6/7'de çalışır

this.http.post("http://destinationurl.com/endpoint", fileFormData)
  .subscribe(response => {
    //handle response
  }, err => {
    //handle error
  });

İşte tam uygulama


1

jspdf ve Açısal 8

Ben bir pdf oluşturmak ve POST isteği ile pdf yüklemek istiyorum, bu nasıl (Netlik için, bazı kod ve hizmet katmanı silmek)

import * as jsPDF from 'jspdf';
import { HttpClient } from '@angular/common/http';

constructor(private http: HttpClient)

upload() {
    const pdf = new jsPDF()
    const blob = pdf.output('blob')
    const formData = new FormData()
    formData.append('file', blob)
    this.http.post('http://your-hostname/api/upload', formData).subscribe()
}

0

Referans kullanarak dosya yükledim. Dosyayı bu şekilde yüklemek için paket gerekmez.

// .ts dosyasına yazılacak kod

@ViewChild("fileInput") fileInput;

addFile(): void {
let fi = this.fileInput.nativeElement;
if (fi.files && fi.files[0]) {
  let fileToUpload = fi.files[0];
    this.admin.addQuestionApi(fileToUpload)
      .subscribe(
        success => {
          this.loading = false;
          this.flashMessagesService.show('Uploaded successfully', {
            classes: ['alert', 'alert-success'],
            timeout: 1000,
          });
        },
        error => {
          this.loading = false;
          if(error.statusCode==401) this.router.navigate(['']);
          else
            this.flashMessagesService.show(error.message, {
              classes: ['alert', 'alert-danger'],
              timeout: 1000,
            });
        });
  }

}

// service.ts dosyasına yazılacak kod

addQuestionApi(fileToUpload: any){
var headers = this.getHeadersForMultipart();
let input = new FormData();
input.append("file", fileToUpload);

return this.http.post(this.baseUrl+'addQuestions', input, {headers:headers})
      .map(response => response.json())
      .catch(this.errorHandler);

}

// html ile yazılacak kod

<input type="file" #fileInput>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.