我正在尝试通过Angular 5将图像发送到节点我遇到的问题是,当我尝试它时,Angular发送一个空的Json文件
这是HTML5代码:
<input (change)="onFileSelected($event)" type="file" class="custom-file-input" name="file" id="file" accept="image/gif, image/jpg, image/jpeg" >
<button type="button" (click)="onUpload()" class="btn btn-info btn-block">upload</button>
这是component.ts中的代码
onFileSelected(event){
this.selectedFile = event.target.files[0];
console.log(event);
}
onUpload(){
const fd = new FormData();
fd.append('file',this.selectedFile, this.selectedFile.name);
this.authService.onUpload(fd).subscribe(data=>{
if(!data.success){
this.messageClass = 'alert alert-danger'; // Set bootstrap error class
this.message = data.message; // Set error message
console.log(data.message);
}else{
this.messageClass = 'alert alert-success'; // Set bootstrap error class
this.message = data.message; // Set error message
console.log('it worked');
}
});
}
当我上传没有标题的文件并驱散后端检查程序时,它可以正常工作,但我需要对请求进行一种授权,因此需要一个令牌文件
令牌创建的代码
// Function to create headers, add token, to be used in HTTP requests
createAuthenticationHeaders() {
this.loadToken(); // Get token so it can be attached to headers
// Headers configuration options
this.options = new RequestOptions({
headers: new Headers({
'Content-Type': 'application/json', // Format set to JSON
'authorization': this.authToken // Attach token
})
});
}
loadToken() {
this.authToken = localStorage.getItem('token'); // Get token and asssign to variable to be used elsewhere
}
服务代码
// Function to get user's upload image
onUpload(fd){
this.createAuthenticationHeaders(); // Create headers before sending to API
return this.http.post(this.domain + '/authentication/profileImage',fd , this.options).map(res => res.json());
}
所以现在每当我发出请求时,它都会转到Json,我怎么能把它作为文件类型
我创建了一个新函数并更改了Content-Type
createAuthenticationHeadersForFiles() {
this.loadToken(); // Get token so it can be attached to headers
// Headers configuration options
this.option = new RequestOptions({
headers: new Headers({
'Content-Type': 'application/form-data', // Format set to FormData
'authorization': this.authToken // Attach token
})
});
}
// Function to get token from client local storage
loadToken() {
this.authToken = localStorage.getItem('token'); // Get token and asssign to variable to be used elsewhere
}
但它没有按预期工作,无法保存图像
使用Node
的后端代码/* ===============================================================
Route to post user's profile image
=============================================================== */
// init gfs
let gfs;
const conn = mongoose.createConnection('mongodb://localhost:27017/zaad');
conn.once('open',()=>{
gfs = Grid(conn.db,mongoose.mongo);
gfs.collection('profileImages');
});
const storage = new GridFsStorage({
url:config.uri,
file:(req,file)=>{
return new Promise((resolve,reject)=>{
crypto.randomBytes(16,(err,buf)=>{
if(err){
return reject(err);
}
const filename = buf.toString('hex')+ path.extname(file.originalname);
const fileinfo = {
filename:filename,
bucketName:'profileImages'
};
resolve(fileinfo);
});
});
}
});
const upload = multer({storage});
router.post('/profileImage',upload.single('file'),(req,res)=>{
if(!req.file){
res.json({success:false , message:'no image was provided'});
}else{
res.json({file:req.file});
}
});
然后使用Chrome中的devtool我尝试分析请求和结果
General:
Request URL: http://localhost:8080/authentication/profileImage
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Response Headers:
Access-Control-Allow-Origin: http://localhost:4200
Connection: keep-alive
Content-Length: 51
Content-Type: application/json; charset=utf-8
Date: Sat, 26 May 2018 11:17:16 GMT
ETag: W/"33-cBZTT/RGV75GPZIbsrhHP7Mg3SM"
Vary: Origin
X-Powered-By: Express
Request Headers:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ar,en-US;q=0.9,en;q=0.8,fr;q=0.7
authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1YWYzZDM4ZWE1MWM0ZjMxNzhlYWFkN2QiLCJpYXQiOjE1MjczMzI3NzksImV4cCI6MTUyNzQxOTE3OX0.78SoKSz5KlIQB-sh3oZjrfiot9cFLUuH79Q-DgRmSag
Connection: keep-alive
Content-Length: 763935
Content-Type: application/form-data
Host: localhost:8080
Origin: http://localhost:4200
Referer: http://localhost:4200/edit-profile/5af3d38ea51c4f3178eaad7d
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Request Payload:
------WebKitFormBoundaryUq12HhowsrOlY9bF
Content-Disposition: form-data; name="file"; filename="erp-img.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryUq12HhowsrOlY9bF--
答案 0 :(得分:0)
问题似乎出现在“ createAuthenticationHeaders()”函数中。在此功能中,您将 Content-Type 设置为“ application / json ”,而是将其设置为“ multipart / form-data ”或“< em> application / form-data “(以适用于您的方式),以便您更新的createAuthenticationHeaders()方法: -
createAuthenticationHeaders() {
this.loadToken(); // Get token so it can be attached to headers
// Headers configuration options
this.options = new RequestOptions({
headers: new Headers({
'Content-Type': 'application/form-data', // or any other appropriate type as per requirement
'authorization': this.authToken // Attach token
})
});
}
----------------------------- EDIT ----------------- -------
由于您的请求有效负载显示: -
------WebKitFormBoundaryUq12HhowsrOlY9bF
Content-Disposition: form-data; name="file"; filename="erp-img.jpg"
Content-Type: image/jpeg
这意味着客户端工作正常。问题出在服务器端。