나는 이것이 일반적인 질문이라는 것을 알고 있지만 Angular 2에서 파일을 업로드하지 못했습니다.
1) http://valor-software.com/ng2-file-upload/ 및
2) http://ng2-uploader.com/home
...하지만 실패했습니다. Angular에서 파일을 업로드 한 사람이 있습니까? 어떤 방법을 사용 했습니까? 그렇게하는 방법? 샘플 코드 또는 데모 링크가 제공되면 정말 감사하겠습니다.
나는 이것이 일반적인 질문이라는 것을 알고 있지만 Angular 2에서 파일을 업로드하지 못했습니다.
1) http://valor-software.com/ng2-file-upload/ 및
2) http://ng2-uploader.com/home
...하지만 실패했습니다. Angular에서 파일을 업로드 한 사람이 있습니까? 어떤 방법을 사용 했습니까? 그렇게하는 방법? 샘플 코드 또는 데모 링크가 제공되면 정말 감사하겠습니다.
답변:
Angular 2는 파일 업로드를 잘 지원합니다. 타사 라이브러리가 필요하지 않습니다.
<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)
)
}
}
@ angular / core "사용 :"~ 2.0.0 "및 @ angular / http :"~ 2.0.0 "
headers.append('enctype', 'multipart/form-data');
( 'Content-Type'을 대체하기 위해 'enctype'을 사용했습니다). 서버 측 코드에 따라 다를 수 있습니다. (ie api)
위의 답변에서 Angular 5.x로 이것을 만듭니다.
전화 uploadFile(url, file).subscribe()
를 걸어 업로드를 시작하세요
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);
}
}
컴포넌트에서 이와 같이 사용하십시오
// 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");
}
)
}
let params = new HttpParams(); let headers = new HttpHeaders({ 'Authorization': 'Bearer ' + localStorage.getItem('accessToken'), }); const options = { headers: headers, params: params, reportProgress: true, };
Observable
하고이 HttpEvent
에 대한 함수의 반환 형식을 제공하는 형식 유추를 사용하여 전적으로 만약 당신이있는 거 괜찮 생략 할 수있다 uploadFile()
! this.http.request()
는 이미의 유형을 반환 Observable<HttpEvent<{}>>
하므로 요청 호출에 일반 유형을 제공하면 (즉 this.http.request<any>()
, 전체 함수가 올바른 유형으로 만 작동 함)
input type="file" (change)="addFiles($event)" style="display: none" #file multiple> <button mat-raised-button color="primary" (click)="selectFile($event)">Upload File </button>
@Eswar에게 감사합니다. 이 코드는 완벽하게 작동했습니다. 솔루션에 특정 사항을 추가하고 싶습니다.
오류가 발생했습니다. java.io.IOException: RESTEASY007550: Unable to get boundary for multipart
이 오류를 해결하려면 "Content-Type" "multipart / form-data"를 제거해야합니다. 내 문제를 해결했습니다.
multipart/form-data; boundary=---------------------------186035562730765173675680113
. stackoverflow.com/a/29697774/1475331 및 github.com/angular/angular/issues/11819 도 참조하십시오 .
java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found"
과 비슷한 이 오류 를 겪고 있지만 Content-Type
헤더를 제거하면 대신 백엔드에서 404를 얻습니다. 우리는 Spring과 Angular 2를 사용하고 있습니다.
코드 샘플이 약간 구식이기 때문에 Angular 4.3과 새로운 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
}
Angular 2+에서는 Content-Type을 비워 두는 것이 매우 중요 합니다 . 'Content-Type'을 'multipart / form-data'로 설정하면 업로드가 작동하지 않습니다!
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)
);
}
}
}
나는 프라이밍에서 다음 도구를 성공적으로 사용했습니다. primeNg 게임에 스킨이 없으며 제안을 전달합니다.
이 간단한 솔루션은 나를 위해 일했습니다 : file-upload.component.html
<div>
<input type="file" #fileInput placeholder="Upload file..." />
<button type="button" (click)="upload()">Upload</button>
</div>
그런 다음 XMLHttpRequest 를 사용하여 컴포넌트에서 직접 업로드하십시오 .
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);
}
}
}
닷넷 코어를 사용하는 경우 매개 변수 이름은 From 필드 이름과 일치해야합니다. 이 경우 파일 :
[HttpPost("[action]")]
public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files)
{
return await _binaryService.UploadFilesAsync(files);
}
이 답변은 http://blog.teamtreehouse.com/uploading-files-ajax 의 소풍입니다
편집 : 업로드 후 사용자가 새 파일을 선택할 수 있도록 파일 업로드를 지워야합니다. XMLHttpRequest를 사용하는 대신 fetch를 사용하는 것이 좋습니다.
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);
});
}
ng2-file-upload 및 ng2-file-upload없이 파일을 업로드하는 방법에 대한 유용한 자습서 입니다.
나를 위해 그것은 많은 도움이됩니다.
현재 튜토리얼에는 몇 가지 실수가 있습니다.
1- 클라이언트는 서버와 동일한 업로드 URL을 가져야 app.component.ts
합니다.
const URL = 'http://localhost:8000/api/upload';
에
const URL = 'http://localhost:3000';
2-서버가 응답을 'text / html'로 전송하므로 app.component.ts
변경
.post(URL, formData).map((res:Response) => res.json()).subscribe(
//map the success function and alert the response
(success) => {
alert(success._body);
},
(error) => alert(error))
에
.post(URL, formData)
.subscribe((success) => alert('success'), (error) => alert(error));
양식 필드가있는 이미지를 업로드하려면
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);
}
제 경우에는 C #에서 .NET Web Api가 필요했습니다.
// 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);
}
오늘은 ng2-file-upload 패키지를 angular 6 응용 프로그램 에 통합 했습니다. 매우 간단했습니다. 아래 고급 코드를 찾으십시오.
ng2- 파일 업로드 모듈 가져 오기
app.module.ts
import { FileUploadModule } from 'ng2-file-upload';
------
------
imports: [ FileUploadModule ],
------
------
구성 요소 ts 파일 가져 오기 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);
}
------
------
컴포넌트 HTML 추가 파일 태그
app.component.html
<input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" />
온라인 작업 stackblitz 링크 : https://ng2-file-upload-example.stackblitz.io
Stackblitz 코드 예 : https://stackblitz.com/edit/ng2-file-upload-example
jspdf와 Angular 8
pdf를 생성하고 POST 요청으로 pdf를 업로드하고 싶습니다.
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()
}
참조를 사용하여 파일을 업로드했습니다. 이 방법으로 파일을 업로드하는 데 패키지가 필요하지 않습니다.
// .ts 파일로 작성 될 코드
@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 파일에 작성 될 코드
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로 작성 될 코드
<input type="file" #fileInput>