Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 5 Http POST请求转换为选项并返回404_Angular_Http - Fatal编程技术网

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