node.js - 我想使用 http 发布请求将带有图像的表单数据从 Angular 上传到 Node.js?
问题描述
html:在这些模板中,我要求提供产品信息和图像并存储它。
<input type="hidden" formControlName="_id">
<input type="file" formControlName="ProductImage" #ProductImage>
<mat-form-field>
<input formControlName="productName" matInput placeholder="Product Name" #productName>
<mat-hint align="end">{{ productName.value.length }}/50</mat-hint>
<mat-error *ngIf="productForm.get('productName').hasError('required') && productForm.get('productName').touched; else patternproductName;">This is required</mat-error>
<ng-template #patternproductName>
<mat-error *ngIf="productForm.get('productName').hasError('pattern'); else lengthproductName;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthproductName>
<mat-error *ngIf="productForm.get('productName').hasError('minlength') || productForm.get('productName').hasError('maxlength');">Must be 1-50 characters</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="supplierId" matInput placeholder="Supplier" #supplierId>
<mat-option *ngFor="let a of supplierArray" value="{{ a._id }}">{{ a.supplierName }}</mat-option>
</mat-select>
<mat-error *ngIf="productForm.get('supplierId').hasError('required') && productForm.get('supplierId').touched; else patternsupplierId;">This is required</mat-error>
<ng-template #patternsupplierId>
<mat-error *ngIf="productForm.get('supplierId').hasError('pattern'); else lengthsupplierId;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthsupplierId>
<mat-error *ngIf="productForm.get('supplierId').hasError('minlength') || productForm.get('supplierId').hasError('maxlength');">Must be 1-24 characters</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="brandId" matInput placeholder="Brand" #brandId>
<mat-option *ngFor="let a of brandArray" value="{{ a._id }}">{{ a.brandName }}</mat-option>
</mat-select>
<mat-error *ngIf="productForm.get('brandId').hasError('required') && productForm.get('brandId').touched; else patternbrandId;">This is required</mat-error>
<ng-template #patternbrandId>
<mat-error *ngIf="productForm.get('brandId').hasError('pattern'); else lengthbrandId;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthbrandId>
<mat-error *ngIf="productForm.get('brandId').hasError('minlength') || productForm.get('brandId').hasError('maxlength');">Must be 1-24 characters</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="categoryId" matInput placeholder="Category" #categoryId>
<mat-option *ngFor="let a of categoryArray" value="{{ a._id }}">{{ a.categoryName }}</mat-option>
</mat-select>
<mat-error *ngIf="productForm.get('categoryId').hasError('required') && productForm.get('categoryId').touched; else patterncategoryId;">This is required</mat-error>
<ng-template #patterncategoryId>
<mat-error *ngIf="productForm.get('categoryId').hasError('pattern'); else lengthcategoryId;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthcategoryId>
<mat-error *ngIf="productForm.get('categoryId').hasError('minlength') || productForm.get('categoryId').hasError('maxlength');">Must be 1-20 characters</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<input formControlName="productPrice" matInput placeholder="Price" #productPrice>
<mat-hint align="end">{{ productPrice.value.length }}/5</mat-hint>
<mat-error *ngIf="productForm.get('productPrice').hasError('required') && productForm.get('productPrice').touched; else patternproductPrice;">This is required</mat-error>
<ng-template #patternproductPrice>
<mat-error *ngIf="productForm.get('productPrice').hasError('pattern'); else lengthproductPrice;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthproductPrice>
<mat-error *ngIf="productForm.get('productPrice').hasError('min') || productForm.get('productPrice').hasError('max');">Must be between 1-99999</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<input formControlName="productQuantity" matInput placeholder="Quantity" #productQuantity>
<mat-hint align="end">{{ productQuantity.value.length }}/5</mat-hint>
<mat-error *ngIf="productForm.get('productQuantity').hasError('required') && productForm.get('productQuantity').touched; else patternproductQuantity;">This is required</mat-error>
<ng-template #patternproductQuantity>
<mat-error *ngIf="productForm.get('productQuantity').hasError('pattern'); else lengthproductQuantity;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthproductQuantity>
<mat-error *ngIf="productForm.get('productQuantity').hasError('min') || productForm.get('productQuantity').hasError('max');">Must be between 1-99999</mat-error>
</ng-template>
</mat-form-field>
<mat-form-field>
<input formControlName="productMin" matInput placeholder="Minimum" #productMin>
<mat-hint align="end">{{ productMin.value.length }}/5</mat-hint>
<mat-error *ngIf="productForm.get('productMin').hasError('required') && productForm.get('productMin').touched; else patternproductMin;">This is required</mat-error>
<ng-template #patternproductMin>
<mat-error *ngIf="productForm.get('productMin').hasError('pattern'); else lengthproductMin;">Invalid characters</mat-error>
</ng-template>
<ng-template #lengthproductMin>
<mat-error *ngIf="productForm.get('productMin').hasError('min') || productForm.get('productMin').hasError('max');">Must be between 0-99999</mat-error>
</ng-template>
</mat-form-field>
<button mat-raised-button class="pull-right" [mat-dialog-close]="true">Cancel</button>
<button type="submit" mat-raised-button color="primary" class="pull-right" *ngIf="!formSelector" [disabled]="!productForm.valid" (click)="openSnackBar(productNotification)">Create</button>
<button type="submit" mat-raised-button color="primary" class="pull-right" *ngIf="formSelector" [disabled]="!productForm.valid" (click)="openSnackBar(productNotification)">Update</button>
</form>
</ng-template>
这是当用户完成表单并单击提交按钮时执行的打字稿文件。我想获取图像作为 wend 并将其加入 productSchema 并通过使用服务
.ts 将其发送到节点服务器:
productSubmit(form){
const Image = this.Product_Image.nativeElement;
if(Image.files && Image.files[0]){
this.ProductImageFile = Image.files[0];
}
const ImageFile: File = this.ProductImageFile;
let productSchema: productSchema = {
'_id': form.value._id,
'productImage': ImageFile,
'productName': form.value.productName,
'supplierId': form.value.supplierId,
'brandId': form.value.brandId,
'categoryId': form.value.categoryId,
'productPrice': form.value.productPrice,
'productQuantity': form.value.productQuantity,
'productMin': form.value.productMin
};
console.log(productSchema);
if(!this.formSelector){ //create method
this.productService.productCreate(productSchema).subscribe(result =>{
this.notif = "created";
this.productForm.reset();
this.productSelect();
});
}
}
架构:这是我要在所有字段中实现的架构
const mongoose = require('mongoose');
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
const productSchema = mongoose.Schema({
ProductImage: {
type: String,
required: true
},
productName: {
type: String,
required: true,
minlength: 1,
maxlength: 50
},
supplierId: {
type: ObjectId,
required: true,
minlength: 24,
maxlength: 24
},
brandId: {
type: ObjectId,
required: true,
minlength: 24,
maxlength: 24
},
categoryId: {
type: ObjectId,
required: true,
minlength: 24,
maxlength: 24
},
productPrice: {
type: Number,
required: true,
minlength: 1,
maxlength: 5
},
productQuantity: {
type: Number,
required: true,
minlength: 1,
maxlength: 5
},
productMin: {
type: Number,
required: true,
minlength: 1,
maxlength: 5
},
productExist: {
type: Boolean,
required: true,
default: true
},
productTimeStamp: {
type: Date,
required: true,
default: Date.now
}
});
module.exports = mongoose.model('productSchema', productSchema);
这是将表单数据发送到 nodejs服务的
服务:
productCreate(val){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:3000/api/productCreate', val, { headers: headers }).pipe(map(res => res.json()));
}
节点.js
var store = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads');
},
filename: (re, file, cb) => {
cb(null, Date.now() + '.' + file.originalname);
console.log(file);
}
});
//start saving picture
var upload = multer({storage: store}).single('file');
router.post('/upload', (req, res, next) => {
upload(req, res, (err) => {
if(err) return res.status(501).json({ error: err });
return res.json({ originalname: req.file.originalname, uploadname: req.file.filename });
});
});
//end saving picture
router.post('/productCreate', upload, (req, res, next) =>{
console.log(req);
let newproductSchema = new productSchema({
productImage: req.file,
productName: req.body.productName,
supplierId: req.body.supplierId,
brandId: req.body.brandId,
categoryId: req.body.categoryId,
productPrice: req.body.productPrice,
productQuantity: req.body.productQuantity,
productMax: req.body.productMax,
productMin: req.body.productMin
});
console.log(newproductSchema);
newproductSchema.save((err, newproductSchema) =>{
if(err) res.json(err);
else res.json({msg: 'Item added successful'});
});
});
我想创建一个将产品信息和图像也保存到 mongodb 的系统。我想将图像的路径存储在数据库中。我对如何将文件从角度发送到节点感到困惑。你能帮我解决这些问题吗?谢谢你。我想用一张图片上传表单数据。但我做不到。我该如何解决这些问题?
解决方案
您可以将图像放入画布,然后从画布中检索 blob 或 dataUrl,将其作为属性附加到您正在使用的服务器的 get/post 请求中,并将图像作为字节块直接存储在 MongoDB 中或一个 base64 编码的字符串。要检索它,您只需将图像的 src 设置为存储在 MonoDB 中的 dataUrl。
示例: https ://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
推荐阅读
- powershell - Powershell Expand-Archive 西里尔文名称
- angular - 如何使用 jboss 6.4 刷新角度?
- javascript - 悬停时 CSS 的背景形状
- google-maps-embed - 嵌入没有 cookie 的谷歌地图
- spring-cloud-stream - 将 Solace Binder 与 Spring Cloud Stream 一起使用
- react-native - 调用getCurrentPositionAsync exo sdk 34时无法在ios中获取当前位置错误
- php - $_GET['name']) 正在获取输入 name='name' 的值作为空
- node.js - eventEmitter回调后Node.js http请求关闭响应
- junit - 从类中声明的私有静态变量调用的模拟静态方法
- java - 如何在字符串中获取字符串(yaml)