如何解决Angular和NodeJ中的文件上传问题?

时间:2019-08-20 12:19:14

标签: node.js angular multer

我正在尝试通过网络浏览器上传文件,但我不能这样做。当我通过邮递员保存此api时,然后上传了文件,但无法尝试通过Web浏览器上传文件。当我尝试通过网络浏览器上传文件时,我在服务器端收到了类似“ SyntaxError:Unexpected token-in JSON at position 0”的错误。

我正在使用NodeJS,ExpressJs作为后端以及Angular 6作为前端。

角度

html

<div>
  <div>
    <input type="file" (change)="createFormData($event)">
  </div>
  <button (click)="upload()">Upload</button>
</div>

ts

export class PhotographComponent implements OnInit {
  selectedFile: File = null;
  fd = new FormData();

  constructor(private formBuilder: FormBuilder, private httpClient: 
  HttpClient) {}

  ngOnInit() {}

  createFormData(event) {
    this.selectedFile = <File>event.target.files[0];
    this.fd.append('photo', this.selectedFile, this.selectedFile.name);
  }

  upload() {
    this.httpClient.post(environment.apiUrl + 'photographs', this.fd)
      .subscribe( result => {
        console.log(result);
      });
  }

}

NodeJs

const { Photograph, validate } = require('../models/photograph');
const multer  = require('multer');
const express = require('express');
const router = express.Router();

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
    }
})

const upload = multer({
    storage: storage
})

// save photograph
router.post('/', upload.single('photo'), (req, res) => {
    console.log(req.file);
    const filename = req.file.filename;
    const path = req.file.path;

    res.json({message: 'File uploaded'});
})

module.exports = router;

请帮助我找到上传文件的解决方案。 谢谢。

3 个答案:

答案 0 :(得分:1)

实际上我已经找到了解决方案。我的后端(NodeJs)代码正确。我已经对前端(Angular)进行了一些更改。

角度

html

<input id="photo" type="file" />

<button type="button" (click)="upload()">
  Upload
</button>

ts

upload() {
let inputEl: HTMLInputElement = this.el.nativeElement.querySelector('#photo');
console.log("iam+ " + inputEl);
let fileCount: number = inputEl.files.length;
let formData = new FormData();
if (fileCount > 0) { // a file was selected
  for (let i = 0; i < fileCount; i++) {
    formData.append('photo', inputEl.files.item(i));
  }

  this.httpClient.post(URL, formData)
    .subscribe((res) => {
        console.log('Upload Success');
      },
      msg => {
        console.error(`Error: ${msg.status} ${msg.statusText}`);
      }
    );
  }

}

答案 1 :(得分:0)

在客户端的请求标头中

添加'Accept':'application / json'

private getHeaders() {
    const headers = new HttpHeaders({
      'Accept': 'application/json',
    });
    return headers;
  }
    upload() {
        this.httpClient.post(environment.apiUrl + 'photographs', this.fd,{ headers: this.getHeaders() })
          .subscribe( result => {
            console.log(result);
          });
      }

然后在Nodejs应用程序中的中间件的响应标头中添加“接受”

    app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization, PublicKey"
    );
    next();
});

答案 2 :(得分:0)

似乎您面临着httpInterceptor问题,我也遇到过同样的问题, 您可以覆盖httpInterceptor或创建新的httpClient。

这可以帮助您:

export class PhotographComponent implements OnInit {
  private customHttpClient: HttpClient;
  selectedFile: File = null;
  fd = new FormData();

  constructor(private formBuilder: FormBuilder, private httpClient: 
  HttpClient, private handler: HttpBackend) {
     this.customHttpClient = new HttpClient(handler);
  }

  ngOnInit() {}

  createFormData(event) {
    this.selectedFile = <File>event.target.files[0];
    this.fd.append('photo', this.selectedFile, this.selectedFile.name);
  }

  upload() {
     const httpOptions = {
         headers: new HttpHeaders({
         'Accept': 'application/json',
         //'Authorization': 'Bearer '+ token,
       })
     };

    this.customHttpClient.post(environment.apiUrl + 'photographs', this.fd, httpOptions )
      .subscribe( result => {
        console.log(result);
      });
  }

}