我正在尝试向使用ExpressJS开发的REST API发送HTTP Post请求。我正在使用Angular的HttpClient并使用以下服务文件发送请求:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJ0ZXN0MiIsImxldmVsIjoxLCJpYXQiOjE1NTYyMDU0OTMsImV4cCI6MTU1NjI5MTg5M30.luqbDb-sSLxsX0LKFTaF6NTYDO4tS6kCI8V_d9pizmA'
})
};
@Injectable({
providedIn: 'root'
})
export class ApiserviceService {
constructor(private http: HttpClient) { }
getData(url: string) {
return this.http.get(url)
}
postData(url: string, data: Object) {
console.log(data);
return this.http.post(url, data, httpOptions)
}
}
使用以下代码调用服务:
/* other Component class code */
constructor(private data: ApiserviceService) {}
submit()
{
let url: string =
"http://xxx.xxx/api/hotels/"
+ this.route.snapshot.params.hotelId
+ "/reviews";
this.data.postData(url, this.revForm.value).subscribe(data => {
console.log(data);
this.router.navigate(['/']);
});
}
我必须添加一个授权标头,因为API会拒绝所有不带有令牌的请求。
在服务文件中http.post语句上方的控制台日志中,我正完全按需获取数据,一个带有所有必需参数的JSON对象已打印在Google Chrome的控制台上。但是,由于某种原因,Angular应用正在发送一个空请求。
我在响应中遇到了缺失值错误,因此为了找出原因,我在错误处理的API控制器中添加了以下行:
console.log(要求正文);
这是API中的函数:
var _addReview = function(req, res, data) {
data.reviews.push({
name : req.body.name,
rating : parseInt(req.body.rating, 10),
review : req.body.review,
id : req.userid
});
data.save(function(err, hotelUpdated){
if(err) {
console.log(req.body);
res.status(500).json(err);
}
else {
res.status(201).json(hotelUpdated.reviews[hotelUpdated.reviews.length - 1]);
}
});
};
NodeJS的控制台打印了一个空对象{}。我尝试将Content-Type更改为application / json,但还是没有运气。
我还注意到在NodeJS控制台中,我的Angular应用正在POST请求之前发送OPTIONS请求。我在线检查了一下,发现POST请求仅在OPTIONS请求返回200码后才发送。但是,由于我收到响应,因此正在发送我的POST请求。因此,我认为OPTIONS请求已成功完成。
即使当我发送与Angular应用程序中完全相同的标头时,我的API在Postman中也能正常工作。
答案 0 :(得分:1)
通过发送内容类型为application / json而不是application / x-www-form-urlencoded的请求解决了该问题。显然,Angular并未像Postman那样将application / x-www-form-urlencoded转换为json可解析的数据。
答案 1 :(得分:0)
您是否在路由处理中使用body-parser中间件?
请参见以下示例:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
答案 2 :(得分:0)
对于CORS
,OPTIONS
调用(仅标头且没有正文)需要为taken care of