Я пытаюсь отправить файл jpg в кодировке base64 на сервер nodejs. Я получаю сообщение об ошибке c CORS 'Multi-origin запрос заблокирован (кросс-источник): критерий соответствия источника не позволяет читать удаленный ресурс с http: // localhost: 8080 / uploadCarImage? Изображение = данные: изображение / JPEG; base64. .. 'также осматривая консоль браузера, я вижу еще одну ошибку' 404 Bad Request '. Другие http-вызовы на сервер работают правильно. Как мне решить эти ошибки? Спасибо!
ОБНОВЛЕНИЕ: снимок экрана ошибок
Вот код.
продать -new-car.component.ts:
import { Component, OnInit } from '@angular/core';
import * as _ from 'lodash';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { CarUploadService } from '../services/car-upload.service';
import { AuthenticationService } from '../services/authentication.service';
@Component({
selector: 'app-sell-new-car',
templateUrl: './sell-new-car.component.html',
styleUrls: ['./sell-new-car.component.css']
})
export class SellNewCarComponent implements OnInit {
imageError: string[] = [null, null, null];
isImageSaved: boolean[] = [false, false, false];
cardImageBase64: string[] = [null, null, null];
imgBase64Path = [null, null, null];
imageUrl: string[] = [null, null, null];
step:boolean[] = [true, false, false, false, false];
uploading:boolean = false;
// Size Filter Bytes
max_size = 1048576; // 1MB
allowed_types = ['image/png', 'image/jpeg'];
height = 300;
width = 300;
detailsForm: FormGroup;
carId: number;
brand: any;
model: any;
userId: number;
constructor(private formBuilder: FormBuilder, private carUploadService: CarUploadService, private authenticationService:AuthenticationService) { }
ngOnInit() {
this.detailsForm = this.formBuilder.group({
brand: ['', Validators.required],
model: ['', Validators.required],
});
}
// convenience getter for easy access to form fields
get f() { return this.detailsForm.controls; }
fileChangeEvent(fileInput: any, formN:number) {
this.imageError[formN] = null;
this.cardImageBase64[formN] = null;
this.isImageSaved[formN] = false;
if (fileInput.target.files && fileInput.target.files[0]) {
if (fileInput.target.files[0].size > this.max_size) {
//this.imageError = 'Maximum size allowed is ' + max_size / 1000000 + 'MB';
this.imageError[formN] = 'Maximum size allowed is 1 MB';
return false;
}
if (!_.includes(this.allowed_types, fileInput.target.files[0].type)) {
this.imageError[formN] = 'Only Images are allowed ( JPG | PNG )';
return false;
}
const reader = new FileReader();
reader.onload = (e: any) => {
const image = new Image();
image.src = e.target.result;
image.onload = rs => {
const img_height = rs.currentTarget['height'];
const img_width = rs.currentTarget['width'];
if (img_height != this.height || img_width != this.width) {
this.imageError[formN] = 'Dimentions allowed ' + this.height + '*' + this.width + 'px';
return false;
} else {
let me = this;
let reader2 = new FileReader();
reader2.readAsDataURL(fileInput.target.files[0]);
reader2.onload = function () {
me.imgBase64Path[formN]= reader2.result;
}
//this.imgBase64Path[formN] = btoa(e.target.result);
this.cardImageBase64[formN] = e.target.result;
this.isImageSaved[formN] = true;
this.imageUrl[formN] = fileInput.target.files[0].name;
console.log('filename='+this.imageUrl[formN]);
// this.previewImagePath = imgBase64Path;
}
};
};
reader.readAsDataURL(fileInput.target.files[0]);
}
}
removeImage(formN) {
this.cardImageBase64[formN] = null;
this.isImageSaved[formN] = false;
}
saveDetails(){
this.brand = this.detailsForm.controls['brand'].value;
this.model = this.detailsForm.controls['model'].value;
this.step[0] = false;
this.step[1] = true;
}
upload(){
this.uploading=true;
this.userId = this.authenticationService.currentUserValue.id;
this.carUploadService.uploadDetails(this.userId, this.model, this.brand).subscribe( data => {
this.carId=data['carId'];
this.uploadImages();
});
}
uploadImages(){
const imagePath = 'CarsImages/';
for(let i=0;i<this.imageUrl.length;i++){
this.carUploadService.uploadImage(this.imgBase64Path[i], i, imagePath+this.imageUrl[i], this.carId).subscribe( data =>{
if(i==2){
this.step[4] = false;
this.step[5] = true;
}
//INSERIRE LA GESTIONE DEGLI ERRORI
});
}
}
nextStep(formN:number){
if(formN == 0){
this.step[1] = false;
this.step[2] = true;
}else if(formN == 1){
this.step[2] = false;
this.step[3] = true;
}if(formN == 2){
this.step[3] = false;
this.step[4] = true;
this.upload();
}
}
}
car-upload.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class CarUploadService {
constructor(private http:HttpClient) { }
headers = {
headers: new HttpHeaders({
'Content-Type' : 'application/json',
'Accept': 'application/json'
})
};
headersImageBase64 = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data'
})
}
uploadDetails(userId, model, brand){
return this.http.post('http://localhost:8080/uploadCarDetails?userId=' + userId +'&model=' + model +'&brand=' + brand, this.headers);
}
uploadImage(image, imageN, imageUrl, carId){
console.log('uploadCarImage');
console.log('imageUrl='+imageUrl);
return this.http.post('http://localhost:8080/uploadCarImage?image=' + image +'&imageN=' + imageN + '&imageUrl=' + imageUrl + '&carId=' + carId , this.headersImageBase64);
}
}
сервер. js
var mysql = require('mysql');
var express = require('express');
var cors = require('cors');
const jwt = require('jsonwebtoken');
var sanitizer = require('sanitizer');
const fs = require("fs")
const fileUpload = require('express-fileupload');
var app = express();
app.use(cors());
// enable files upload
app.use(fileUpload({
createParentPath: true
}));
var connection = mysql.createConnection({
host: '127.0.0.1',
user: 'andrea',
password: 'password',
database: 'cars_market_place'
});
try{
connection.connect();
}catch(err){
console.error("Error:"+err);
}
const RSA_PRIVATE_KEY = fs.readFileSync('./privateKEY.pem');
const passphrase = 'vivalafiga';
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
function LinkMysql(query) {
return new Promise(function(resolve, reject) {
connection.query(query, function(err, result) {
if (err)
console.error(err);
resolve(result);
});
});
}
app.route('/getCars').get(function(request, response){
console.log("/getCars");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
query = 'SELECT `cars`.`id`, `cars`.`model`, `cars`.`brand`, `cars`.`image1`, `cars`.`image2`, `cars`.`image3`, `users`.`id` AS userId, `users`.`username` FROM `cars`, `users` WHERE `users`.`id` = `cars`.`id_user`';
LinkMysql(query).then(function(data) {
response.writeHead(200, {'content-Type': 'text/plain; charset=utf-8'});
console.table(data);
response.end(JSON.stringify(data));
});
});
app.route('/getCarFromId').get(function(request, response){
console.log("/getCar");
// Prevent xss
carId = sanitizer.sanitize(request.query.carId);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
query = 'SELECT `cars`.`id`, `cars`.`model`, `cars`.`brand`, `cars`.`image1`, `cars`.`image2`, `cars`.`image3`, `users`.`id` AS userId, `users`.`username` FROM `cars`, `users` WHERE `users`.`id` = `cars`.`id_user` AND `cars`.`id` = ' + carId;
LinkMysql(query).then(function(data) {
response.writeHead(200, {'content-Type': 'text/plain; charset=utf-8'});
response.end(JSON.stringify(data));
});
});
/*
app.route('/getCarFromModelBrand').get(function(request, response){
console.log("/getCarFromModelBrand");
// Prevent xss
modelS = sanitizer.sanitize(request.query.model);
brandS = sanitizer.sanitize(request.query.brand);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
query = 'SELECT `cars`.`id` FROM `cars` WHERE `cars`.`model` = +' modelS + ' AND `cars.brand``cars`.`id_user` AND `cars`.`id` = ' + carId;
LinkMysql(query).then(function(data) {
response.writeHead(200, {'content-Type': 'text/plain; charset=utf-8'});
response.end(JSON.stringify(data));
});
});
*/
app.route('/getUserByUsername').get( function(request, response){
console.log("/getUserByUsername");
// Prevent xss
var usernameS = sanitizer.sanitize(request.query.username);
console.log("username="+usernameS);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
query = 'SELECT * FROM `users` WHERE `users`.`username` = ' + connection.escape(usernameS);
LinkMysql(query).then(function(data) {
response.writeHead(200, {'content-Type': 'text/plain; charset=utf-8'});
response.end(JSON.stringify(data));
});
});
app.route('/login').post( function(request, response) {
console.log('/login');
let username = request.query.username;
let password = request.query.password;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
if (username && password) {
usernameS = sanitizer.sanitize(request.query.username);
getUserByUsername(connection.escape(usernameS)).then( function(user){
if (!user) {
response.status(401).json({ msg: 'user not found', user: username });
} else{
if (user.password === password) {
jwt.defaul
const jwtBearerToken = jwt.sign({}, {key:RSA_PRIVATE_KEY, passphrase:passphrase}, {
algorithm: 'RS256',
expiresIn: 10000,
})
response.status(200).json({ msg: 'ok', idToken: jwtBearerToken, expiresIn:10000,
user: {id:user.id,
username:user.username,
password:'',
email:user.email,
firstname:user.firstname,
lastname:user.lastname,
token:''
}
});
/*
response.json({ msg: 'ok', idToken: jwtBearerToken, expiresIn:3600,
user: {id:user.id,
username:user.username,
password:'',
email:user.email,
firstname:user.firstname,
lastname:user.lastname,
token:''
}
});
*/
} else {
response.status(401).json({ msg: 'Password is incorrect' });
}
}
}).catch( (err) => {
console.error(err);
});
}
});
app.route('/register').post( function(request, response) {
console.log('register');
let username = request.query.username;
let password = request.query.password;
let firstname = request.query.firstname;
let lastname = request.query.lastname;
let email = request.query.email;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
if (username && password && email) {
// Prevent xss
usernameS = sanitizer.sanitize(username);
passwordS = sanitizer.sanitize(password);
firstnameS = sanitizer.sanitize(firstname);
lastnameS = sanitizer.sanitize(lastname);
emailS = sanitizer.sanitize(email);
getUserByUsername(usernameS).then( function(user){
if (!user) {
console.log("user not found:" + username);
//inserisci nel database
query = 'INSERT INTO `users` (`firstname`, `lastname`, `username`, `password`, `email`) ' +
'VALUES (' + connection.escape(firstnameS) + ', '
+ connection.escape(lastnameS) + ', '
+ connection.escape(usernameS) + ', '
+ connection.escape(passwordS) + ','
+ connection.escape(emailS) + ')';
console.log('query='+query);
connection.query(query, function(err, result) {
if (err)
console.error('error: ' + err);
response.status(200).json({msg:'registration success'});
});
}else{
console.log("username taken:" + username);
response.status(409).json({ msg: 'username taken' });
}
}).catch( (err) => {
console.error(err);
});
}else{
console.error('no data avaiable');
response.status(409).json({ msg: 'no data avaiable' });
}
});
app.route('/uploadCarDetails').post( function(request, response){
console.log('uploadCarDetails');
let userId = request.query.userId;
let model = request.query.model;
let brand = request.query.brand;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
if (userId && model && brand) {
// Prevent xss
userIdS = sanitizer.sanitize(userId);
modelS = sanitizer.sanitize(model);
brandS = sanitizer.sanitize(brand);
query = 'INSERT INTO `cars` (`id_user`, `model`, `brand`) ' +
'VALUES (' + connection.escape(userIdS) + ', '
+ connection.escape(modelS) + ', '
+ connection.escape(brandS) + ')';
console.log('query='+query);
connection.query(query, function(err, result) {
if(err){
console.error('error: ' + err);
response.status(409).json({msg:'error: ' + err});
}else{
query = 'SELECT `id` FROM `cars` WHERE (`model`=' + connection.escape(modelS) + ' AND `brand`=' + connection.escape(brandS) + ')';
LinkMysql(query).then( result => {
var carId = result[0].id;
response.status(200).json({msg:'upload success', carId:carId});
}).catch((err) => {
console.error('error: ' + err);
response.status(409).json({msg:'error: ' + err + '.check server log'});
});
}
});
}else{
console.error('no data avaiable');
response.status(409).json({ msg: 'no data avaiable' });
}
});
app.route('/uploadCarImage').post( function(request, response){
console.log('/uploadCarImage');
let imageN = request.query.imageN || "";
let image = request.query.image || "";
let imageUrl = request.query.imageUrl || "";
let carId = request.query.carId || "";
console.log('imageN='+imageN);
console.log('image='+image);
console.log('imageUrl='+imageUrl);
console.log('carId='+carId);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
response.setHeader("X-Powered-By",' 3.2.1');
response.setHeader("Content-Type", "application/json");
if ( imageN && image && imageUrl && carId) {
imageUrlS = sanitizer.sanitize(imageUrl);
carIdS = sanitizer.sanitize(carId);
console.log('imageUrlS='+imageUrlS);
console.log('imageUrl='+imageUrl);
query='';
if(imageN==0){
query = 'UPDATE `cars` SET `image1` = '+ connection.escape(imageUrlS) + ' WHERE `id` = ' + connection.escape(carIdS);
}else if(imageN==1){
query = 'UPDATE `cars` SET `image2` = '+ connection.escape(imageUrlS) + ' WHERE `id` = ' + connection.escape(carIdS);
}else if(imageN==2){
query = 'UPDATE `cars` SET `image3` = '+ connection.escape(imageUrlS) + ' WHERE `id` = ' + connection.escape(carIdS);
}
console.log('query='+query);
connection.query(query, function(err, result) {
if(err){
console.error('error: ' + err);
response.status(409).json({msg:'error: ' + err});
}else{
response.status(200).json({msg:'upload success'});
}
});
//save image to disk
try{
if(!request.files) {
response.status(409).json({msg:'no file avaiable to upload'});
} else {
//Use the name of the input field (i.e. "avatar") to retrieve the uploaded file
let image = request.files.image;
//Use the mv() method to place the file in upload directory (i.e. "uploads")
image.mv('../src/assets/CarsImages/' + image.url);
//send response
response.status(200).json({msg:'upload success'});
}
}catch(error){
console.error(error);
response.status(409).jsno({msg:'error='+error+'. check server log'});
}
}else{
console.error('no data avaiable');
response.status(409).json({ msg: 'no data avaiable, check server log' });
}
});
function getUserByUsername(username){
return new Promise((resolve, reject) => {
query = 'SELECT * FROM `users` WHERE `users`.`username` = ' + connection.escape(usernameS);
LinkMysql(query).then(function(data) {
resolve(data[0]);
reject(null);
}).catch((err)=> {
console.error('Error:' + err);
});
});
}
app.listen(8080);
console.log('server listening on 8080');