Angular 5 Http POST请求变为OPTIONS并返回404

时间:2018-10-09 17:04:00

标签: angular http

使用:

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);
    }
}

当我订阅此服务时,浏览器向OPTIONS发送预检localhost:3000/my-service请求,该请求返回404。如果我从请求中删除httpOptions,它将成功地将主体需要,但未将Content-Type设置为application/json,因此服务器返回500。

我如何在Angular 5中发送内容类型为json的POST请求?服务器提供了Postman的预期结果,但是我不确定如何说服Angular只需发送带有所需标题的POST。

3 个答案:

答案 0 :(得分:1)

OPTIONS请求不是Angular问题,而是浏览器问题。

当浏览器发出跨域请求时,它将(对于大多数请求,取决于您所请求的内容和所使用的方法)首先发出OPTIONS请求。

OPTIONS请求的目的是检查服务器是否允许您的客户端(浏览器)向其发出请求。这由服务器CORS响应标头确定。如果OPTIONS请求失败,则浏览器会知道这是不允许的,因此不会费心提出您想要的实际请求。

这仅由浏览器强制执行,因此POSTMAN可以正常工作。

请在您的服务器响应中添加CORS标头,并确保您的服务器支持OPTIONS请求。

请参见https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

请参见https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

如果您真的不能对CORS感到困扰,则将请求发送到同一域,并让您的Web服务器重写URL。请注意,您还必须在生产服务器中重复进行重写的逻辑。

答案 1 :(得分:1)

这是由于CORS限制(跨原始资源共享)而发生的。除非服务器允许,否则浏览器不允许请求使用具有不同主机/端口组合的服务器。这是出于安全原因(例如,防止XSRF攻击)。有几种解决方法:

  • 更新服务器以添加允许来自任何来源或给定来源的CORS的标头(如果要允许其他服务器访问API,这是您在实际环境中的做法)。互联网上有很多相关资源,这是一个很好的例子:http://restlet.com/company/blog/2016/09/27/how-to-fix-cors-problems/
  • 在您的客户端和服务器之间添加一个代理来解决该问题(根据我的经验,这是碰碰运气的,但是某些框架(例如ionic)具有有效的代理)。
  • 某些浏览器不如其他浏览器严格,在这种情况下,最严格的浏览器是chrome,它带有一个标志,允许您在开发过程中绕过CORS检查(请谨慎使用,并且在启用此标志时不要访问实际网站,因为可能会使您容易受到XSRF攻击)。标记为:--disable-web-security --user-data-dir=SOME_FOLDER

答案 2 :(得分:0)

我发现开发的最佳解决方案是使用Angular代理。

const proxy = [
  {
    context: '/api',
    target: 'http://localhost:3000',
    pathRewrite: {'^/api' : ''}
  }
];
module.exports = proxy;


ng serve --proxy-config proxy.config.js --open

这会将/api下同一域中的所有请求重新路由回我的服务器,因此我无需担心将服务器配置为替换ng serve