Angular 5 Http POST请求转换为选项并返回404
使用:Angular 5 Http POST请求转换为选项并返回404,angular,http,Angular,Http,使用: 从'@angular/common/http'导入{HttpClient,HttpHeaders}; 常量httpOptions={ 标题:新的HttpHeaders({ '内容类型:['application/json'] }) } @可注射() 导出类MyService{ 构造函数(私有http:HttpClient){} 私有myUrl=http://localhost:3000/my-服务",; 私人postBody= ` [ {“a”:[“复合体”], “序列化”:“数据”,
从'@angular/common/http'导入{HttpClient,HttpHeaders};
常量httpOptions={
标题:新的HttpHeaders({
'内容类型:['application/json']
})
}
@可注射()
导出类MyService{
构造函数(私有http:HttpClient){}
私有myUrl=http://localhost:3000/my-服务",;
私人postBody=
`
[
{“a”:[“复合体”],
“序列化”:“数据”,
“设置”:[],
},{
“in”:“json”,
“格式”:[]
}
]
`;
getData():可观察{
返回this.http.post(this.myUrl、this.postBody、httpOptions);
}
}
当我订阅此服务时,浏览器向localhost:3000/my service
发送飞行前OPTIONS
请求,返回404。如果我从请求中删除httpOptions
,它会成功地发布我想要的正文,但不会将Content-Type
设置为application/json
,因此服务器返回500
如何在Angular 5中发送内容类型为json的POST请求?服务器提供了来自Postman的预期结果,但我不确定如何说服Angular发送带有我想要的标题的帖子。选项请求不是Angular问题,而是浏览器问题 当浏览器发出跨域请求时,它将(对于大多数请求,取决于您请求的内容和使用的方法)首先执行选项请求 选项请求的目的是检查服务器是否允许您的客户端(浏览器)向其发出请求。这由服务器CORS响应头决定。如果选项请求失败,那么浏览器知道这是不允许的,因此不会费心提出您想要的实际请求 这仅由浏览器强制执行,因此邮递员可以正常工作 请将CORS标头添加到服务器响应中,并确保服务器支持选项请求 看 看
如果你真的不喜欢CORS,那么将请求发送到同一个域,让你的Web服务器重写URL。请注意,您还必须在prod服务器中重复重写逻辑。这是由于CORS限制(跨源资源共享)。浏览器不允许将请求发送到具有不同主机/端口组合的服务器,除非服务器允许。这是出于安全原因(例如为了防止XSRF攻击)。有几种方法可以解决这一问题:
- 更新服务器以添加允许来自任何来源或给定来源的COR的标题(如果您希望允许其他服务器访问您的API,那么在真实环境中就是这样做的)。互联网上有很多关于这方面的资源,这是一个很好的例子:
- 在客户机和服务器之间添加一个代理来解决这个问题(根据我的经验,这是偶然的,但是像ionic这样的一些框架有一个工作代理)
- 有些浏览器没有其他浏览器严格,本例中最严格的浏览器chrome有一个标志,允许您在开发过程中绕过CORS检查(请谨慎使用,启用此标志时不要访问真实网站,因为它可能使您容易受到XSRF攻击)。该标志是:
--禁用web安全--用户数据目录=某个文件夹
- 我找到的最佳开发解决方案是使用角度代理
import { HttpClient, HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type: ['application/json']
})
}
@Injectable()
export class MyService {
constructor (private http: HttpClient) {}
private myUrl = 'http://localhost:3000/my-service';
private postBody =
`
[
{ "a": ["complex"],
"serialized": "data",
"set": [],
},{
"in": "json",
"format": []
}
]
`;
getData(): Observable<ExpectedResponseType> {
return this.http.post<ExpectedResponseType>(this.myUrl, this.postBody, httpOptions);
}
}
这将在
/api
下将同一域上的所有请求重新路由回我的服务器,这样我就不必担心配置我的服务器来替换ng serve
即使启用了--禁用web安全
功能,请求仍会转到选项
。您确定--禁用web安全已启用吗?您可能需要关闭所有正在运行的chrome浏览器(我更愿意完全关闭该进程)并尝试。我知道,当我在顶部收到警告“您正在使用不受支持的命令行标志…”时,它会被启用。是的,我收到了标志,但行为是相同的。标头定义中有错误,您可以尝试使用它(即使这是HttpClient afaik中的默认值):标头:new HttpHeaders({'Content Type':'application/json'})此外,您能否尝试重新格式化您的postBody,使其采用javscript对象格式而不是字符串。例如:private postBody=[{a:[“complex”],序列化:“data”,set:[],},{in:“json”,format:[]}];该错误提示CORS,但我认为您的头中有一个数组,这可能是为什么?
const proxy = [
{
context: '/api',
target: 'http://localhost:3000',
pathRewrite: {'^/api' : ''}
}
];
module.exports = proxy;
ng serve --proxy-config proxy.config.js --open