- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在我使用 multer 作为中间件的 Nodejs api 中,我可以在 request.file 属性中看到 postman 发布文件请求,当然,该属性随后会保存在我的服务器上。该请求以内容类型表单数据发送。一旦在我的 Controller 上点击“保存”,文件就已经上传。文件的所有详细信息都在 request.files 属性中
在 Angular 中,附加文件被添加到请求正文中,而我的 Nodejs 应用程序无法保存该文件,因为中间件看不到它。图像数据以 Base64 编码字符串形式出现
我尝试将 Angular 中的标题设置为 multipart/form-data,但收到 500 错误“Multipart:未找到边界”。
在 Postman 中,如果我删除表单数据并将其设置为无,它也不起作用
imageFile:any;
onImagePicked(imageData: string | File) {
if (typeof imageData === 'string') {
try {
/*this.imageFile = this.sharedService.base64toBlob(
imageData.replace('data:image/jpeg;base64,', ''),
'image/jpeg'
);*/
this.imageFile = imageData;
} catch (error) {
console.log('Err' + error);
return;
}
} else {
this.imageFile = imageData;
}
}
savePhoto() {
console.log ('Save');
this.sharedService.uploadPhoto(this.imageFile).subscribe(val => {
console.log(val);
});
}
public uploadPhoto(image: File) {
//let headers = new HttpHeaders();
//headers = headers.append('Content-Type', 'multipart/form-data');
const imageData = new FormData();
imageData.append('image', image);
return this.httpClient.post(environment.apiURL + this.path, imageData);
//return this.httpClient.post(environment.apiURL + this.path, imageData, {headers: headers});
}
public express: express.Application;
constructor() {
this.express = express();
this.setMiddlewares();
this.setRoutes();
this.catchErrors();
this.setSocketServer();
}
private setMiddlewares(): void {
this.express.options('*', cors());
this.express.use(cors());
this.express.use((reg, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Access-Control-Max-Age', 10000);
next();
});
this.express.use(morgan('dev'));
this.express.use(bodyParser.json());
this.express.use(bodyParser.urlencoded({ extended: false }));
this.express.use(helmet());
const storageConfig = multer.diskStorage({
destination: (req, file, callback) => callback(null, './files'),
filename: (req, file, callback) => callback(null, Date.now() + "-" + file.originalname),
});
this.express.use(multer({storage: storageConfig}).any());
}
private setRoutes(): void {
this.express.use('/api', api);
}
import { Router } from "express";
import DfrPhotoController from "./dfrphoto.controller";
const dfrPhoto: Router = Router();
const controller = new DfrPhotoController();
dfrPhoto.post('/', controller.save);
export default dfrPhoto;
export default class DfrPhotoController {
// TODO: link to the dfr
public save = async (req:Request, res:Response): Promise<any> => {
// Need to see files in request. File is already saved in
let files = req.files;
console.log (files);
if (files === null || files === undefined ) {
res.status(404).send({
success: false,
message:'No Files Found'
});
}
console.log("The file was saved!");
res.status(200).send({
success: true,
message:'Photo saved',
data: files
});
}
}
我希望 Angular 文件上传的工作方式与 postman 示例完全相同。我不介意在 Controller 中调用 save 后立即写入文件,因为我可以向中间件添加验证。如果有人对此有任何想法,我将不胜感激
谢谢
//Added Component using the image picker (html and ts)
//HTML
<ion-grid>
<form [formGroup]="form" >
<ion-row size="12">
<ion-col size-lg="6" size-xl="6" size="12" size-md="12">
<app-camera (imagePick)="onImagePicked($event)"></app-camera>
<!-- <ion-thumbnail>
<ion-img width="200" height="200" [src]="imageFile" ></ion-img>
</ion-thumbnail>-->
<img [src]="imageFile" >
</ion-col>
<ion-col size-lg="6" size-xl="6" size="12" size-md="12">
<ion-label position="floating">Photo Comments</ion-label>
<!-- <ion-textarea rows="3" formControlName="rigComments"></ion-textarea>-->
<ion-textarea rows="3" formControlName="photoComments"></ion-textarea>
</ion-col>
</ion-row>
<ion-row>
<ion-button (click)="savePhoto()">Save Photo</ion-button>
</ion-row>
</form>
</ion-grid>
//TS
import { Component, OnInit } from '@angular/core';
import { FormControl, Validators, FormGroup } from '@angular/forms';
import { SharedService } from 'src/app/shared/shared.service';
@Component({
selector: 'app-dfr-photo',
templateUrl: './dfr-photo.component.html',
styleUrls: ['./dfr-photo.component.scss'],
})
export class DfrPhotoComponent implements OnInit {
form: FormGroup;
sharedService: SharedService;
constructor(sharedService: SharedService) {
this.sharedService = sharedService;
}
ngOnInit() {
this.form = new FormGroup({
_id: new FormControl(null, {
updateOn: 'blur',
}),
dfrId: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required]
}),
photoComments: new FormControl(null, {
updateOn: 'blur',
validators: [Validators.required]
}),
image: new FormControl(null, {
updateOn: 'blur'
})
});
}
imageFile:any;
onImagePicked(imageData: string | File) {
if (typeof imageData === 'string') {
try {
/*this.imageFile = this.sharedService.base64toBlob(
imageData.replace('data:image/jpeg;base64,', ''),
'image/jpeg'
);*/
this.imageFile = imageData;
} catch (error) {
console.log('Err' + error);
return;
}
} else {
this.imageFile = imageData;
}
this.form.patchValue({ image: imageData });
this.form.get('image').updateValueAndValidity();
}
savePhoto() {
console.log ('Save');
console.log(this.form.value.image);
this.sharedService.uploadPhoto(this.form.value.image).subscribe(val => {
console.log(val);
});
}
}
// Image Picker Code - JS
import { Component, OnInit, ElementRef, EventEmitter, ViewChild, Output, Input } from '@angular/core';
import { Plugins, CameraResultType, CameraSource, Capacitor} from '@capacitor/core';
import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser';
import { Platform } from '@ionic/angular';
@Component({
selector: 'app-camera',
templateUrl: './camera.component.html',
styleUrls: ['./camera.component.scss'],
})
export class CameraComponent implements OnInit {
@ViewChild('filePicker') filePickerRef: ElementRef<HTMLInputElement>;
@Output() imagePick = new EventEmitter<string | File>();
@Input() showPreview = false;
selectedImage: string;
usePicker = false;
constructor( private sanitizer: DomSanitizer, private platform: Platform) { }
image2: SafeResourceUrl;
ngOnInit() {
if ( this.platform.is('desktop')) {
this.usePicker = true;
}
}
onPickImage() {
if (!Capacitor.isPluginAvailable('Camera')) {
this.filePickerRef.nativeElement.click();
return;
}
Plugins.Camera.getPhoto({
quality: 50,
source: CameraSource.Prompt,
correctOrientation: true,
width: 300,
resultType: CameraResultType.Base64
})
.then(image => {
const image2: any = image; // to fix access to base64 data
this.selectedImage = image2.base64Data;
this.imagePick.emit(image2.base64Data);
})
.catch(error => {
console.log('ERROR ' + error);
if (this.usePicker) {
this.filePickerRef.nativeElement.click();
}
return false;
});
}
onFileChosen(event: Event) {
const pickedFile = (event.target as HTMLInputElement).files[0];
if (!pickedFile) {
return;
}
const fr = new FileReader();
fr.onload = () => {
const dataUrl = fr.result.toString();
this.selectedImage = dataUrl;
this.imagePick.emit(dataUrl);// (pickedFile);
};
fr.readAsDataURL(pickedFile);
}
}
// Image Picker Code - HTML
<div class="picker">
<ion-button color="primary" (click)="onPickImage()" *ngIf="!usePicker">
<ion-icon name="camera" slot="start"></ion-icon>
<ion-label>Take Picture</ion-label>
</ion-button>
</div>
<input
type="file"
accept="image/jpeg"
*ngIf="usePicker"
#filePicker
(change)="onFileChosen($event)"
/>
// Sidenote - Example of sending directly from the form control (renamed to image)
onImagePicked(imageData: string | File) {
if (typeof imageData === 'string') {
try {
/*this.imageFile = this.sharedService.base64toBlob(
imageData.replace('data:image/jpeg;base64,', ''),
'image/jpeg'
);*/
this.imageFile = imageData;
} catch (error) {
console.log('Err' + error);
return;
}
} else {
this.imageFile = imageData;
}
this.form.patchValue({ image: imageData });
this.form.get('image').updateValueAndValidity();
}
savePhoto() {
this.sharedService.uploadPhoto(this.form.value.image).subscribe(val => {
console.log(val);
});
}
最佳答案
我可以建议 Multer 的替代方案吗?
请参阅下面的每周 npm 下载量:
multer: 466,964
formidable: 2,116,997
nodejs服务器:
app.post('/upload', (req, res) => {
var form = new formidable.IncomingForm()
form.parse(req)
form.on('fileBegin', function (name, file) {
var path = __dirname + '/uploads'
if (!fs.existsSync(path)) {
fs.mkdirSync(path)
}
file.path = __dirname + '/uploads/' + file.name;
});
form.on('file', function (name, file) {
console.log('Uploaded ' + file.name);
res.send({ message: 'uploaded' })
});
})
Angular 模板:
<input type="file" (change)="onFileInput($event)" placeholder="Upload file" accept=".JPG,.pdf,.doc,.docx">
Angular 分量:
onFileInput(event) {
let fileList: FileList = event.target.files;
let file = fileList[0]
console.log(file);
let formData: FormData = new FormData();
formData.append('uploadFile', file, file.name);
this.http.post('http://localhost:3001/upload', formData).subscribe(
res => console.log(res)
)
}
关于node.js - 在 Angular 中上传文件 - 显示在 req.body 中,而不是 Nodejs 服务器的 req.files 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55929074/
我的 React 项目需要更新 nodejs。那么我如何将我的 Node js 重新安装到 Ubuntu 16.04 中的最新版本。 我当前的 Node 版本是 node -v v6.0.0 我当前的
我正在寻找逐步调试 NodeJS 服务器代码的有效方法。目前我使用了几十个console.log(),这非常困难。完美的工具可以让我检查堆栈中每个变量的值并逐行跟踪我的程序。首选操作系统 = MacO
我的网站上有以下两个文件: firebase.js gridsome-server.js firebase.js 是一个“常规”javascript 文件,包含以下内容: import firebas
我有一个nodejs应用程序从文件夹A执行,二进制X也在文件夹A中执行(使用子进程exec)。二进制 X 在文件夹 A 中生成输出文件 O,因此始终从调用位置开始。 我需要nodejs应用程序来在仲裁
我有以下nodeJS服务器,它似乎工作正常。我想编写一个客户端,从服务器接收消息并根据消息调用一些 JS。 涉及的步骤是: 用户访问网址http://server.xyz.com:8080/pa no
我想从 Node 服务器进行其余 api 调用。我目前脑子里有请求模块。 您是否会建议用于 Nodejs 中生产实践的 REST 调用(get/post)的任何其他最佳模块? 问候,公羊 最佳答案 R
我正在尝试像这样使用 mainModule: const { mainModule } = require('process'); module.exports = path.dirname(main
我现在对那些版本号真的很困惑。我正在计划一个新项目,想知道这两个版本之间有什么区别。这两个版本之间似乎有很大的跳跃,但现在我找不到区别。 使用 4.1 版安全吗? 感谢您的帮助! 最佳答案 跳转到 v
我试图找到我的问题的解决方案,但找不到,并且正在寻找一些“最佳实践示例”。我有一个 nodejs express 应用程序,我的函数在文件中拆分。例如我有这个 Controller (oktacont
这看起来像是一个非常简单的问题,但作为一个 JS 初学者,我想知道是否可以在 webextension 中使用 NodeJS 模块(例如我想使用这个:https://github.com/yaronn
我有一个文件。a.js class A{ constructor(name){ this.name = name; } displayName(){ conso
我想做的是这样的: node x.js | node y.js 文件 x.js 只是打印一个字符串: console.log("hi"); 文件 y.js 旨在通过 process.stdin 获取字
对于这个新的nodejs debugger I am working on我想对显示的源代码行进行着色。有什么关于 npm 使用的建议吗? 有很多语法荧光笔,但使这种情况有点不同的是 输出是到终端;它
有没有什么方法可以从 ejs View 中引用包含在 node_modules 文件夹中的 Nodejs 库? 我正在使用 expressjs 并且我的客户端库由 /public 文件夹提供,如下所示
我是 NodeJS 的新手,我正在尝试根据 NodeJS 站点上的指南在 NodeJS 中创建一个服务器。我已经在我的电脑上安装了 NodeJS 并使用以下代码制作了 app.js 文件。 const
我有一个 nodejs-express 服务器 (1) 与 mongodb 通信,还有一个 web 服务器 (2) 在 nodejs-express 和 Angularjs 中。我正在尝试发出 pos
我一直在解决(firebase 和 nodejs)问题,这是该问题的第四部分,如何在登录到 server.js 后传递数据 我已经尝试过this但未能使其正常工作。 基本上,我正在尝试将用户idTok
每次页面刷新时,NodeJS 都会在套接字上多次写入数据。当我刷新页面时,nodejs 服务器写入套接字的计数增加,在多个页面刷新时,写入计数固定为 3。 请检查控制台输出是否有此奇怪的响应。请提出同
我在尝试更新文件夹并再次部署其内容时遇到问题。我必须使用 NodeJS 并已获得端口 8080 来使用。我尝试创建一个 php 脚本(update.php): 现在我想启动NodeJS脚本进行更新,
我不明白java多线程系统和Nodejs多线程系统在性能和资源共享方面的区别。由于 NodeJS 为您的程序使用事件循环单线程,但在幕后,它将任务分配给不同的线程,如文件读取或数据库查询。所以它使用多
我是一名优秀的程序员,十分优秀!