【问题标题】:setting HTTP Header for angularjs REST calls为 angularjs REST 调用设置 HTTP 标头
【发布时间】:2014-04-10 06:54:06
【问题描述】:

我正在尝试使用以下代码为我的所有 REST 调用设置 HTTP 标头:

app.factory('authInterceptor', function ($rootScope, $q, $window) {
  return {
    request: function (config) {
      config.headers = config.headers || {};
      config.headers.Authorization = '12345678';
      return config;
    },
    response: function (response) {
      if (response.status === 401) {
        // handle the case where the user is not authenticated
      }
      return response || $q.when(response);
    }
  };
});

app.config(function ($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});

我目前没有在服务器上启用任何授权。 当我省略“config.headers.Authorization = '12345678';”行时,然后 REST 调用运行良好,我得到了我的结果。在 JS 控制台中,我看到了

GET http://localhost:8080/rest/club/1 [HTTP/1.1 200 OK 7ms]

但是当我将这一行放入设置 Header 字段时,我会在 javascript 控制台中看到以下请求

OPTIONS http://localhost:8080/rest/club/1 [HTTP/1.1 200 OK 2ms]

为什么设置 Authorization Header 会将我的方法从“GET”更改为“OPTIONS”?以及如何设置自定义 Header 并且我的请求仍然有效?

改成

config.headers["X-Testing"] = '12345678';

有同样的结果。

编辑:

我尝试了答案,我正在服务器中设置以下 HTTP 标头:

response.getHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost");
response.getHeaders().putSingle("Access-Control-Allow-Header", "X-Testing");
response.getHeaders().putSingle("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.getHeaders().putSingle("Access-Control-Max-Age", 1728000);

我的 REST 服务器在端口 8080 上运行,用于 html/JS 的网络服务器在端口 8000 上(最初使用 file://... 但由于 Origin 为空而移动到单独的网络服务器)

response.getHeaders().putSingle("Access-Control-Allow-Origin", "*");

response.getHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000");

也没有用。

我必须在 OPTIONS 响应中返回任何内容吗?我用与 GET 相同的内容尝试了 200 OK,但我也尝试了 204 No Content。

第二次编辑:

这是 Firefox 为 OPTIONS 方法发送和接收的内容:

【问题讨论】:

    标签: angularjs http-headers


    【解决方案1】:

    您需要在 REST 服务中启用 CORS。正如MDN 中所解释的,添加自定义标头后,http 协议会指定执行预检,

    预检请求

    与简单的请求(上面讨论过)不同,“预检”请求首先 通过 OPTIONS 方法向资源上的资源发送 HTTP 请求 其他域,以判断实际请求是否安全 发送。跨站点请求是这样预检的,因为它们可能 对用户数据有影响。特别是,请求是 预检如果:

    它使用 GET、HEAD 或 POST 以外的方法。此外,如果使用 POST 发送 Content-Type 以外的请求数据 application/x-www-form-urlencoded、multipart/form-data 或 text/plain, 例如如果 POST 请求使用 application/xml 或 text/xml,然后预检请求。它设置 请求中的自定义标头(例如,请求使用标头,例如 X-PINGOTHER)

    除了启用 CORS,您还需要添加一个 Access-Control-Allow-Headers 标头标签来接受您的自定义标头(用于 OPTIONS 响应)。这在 MDN 示例中可见,

    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 01:15:39 GMT
    Server: Apache/2.0.61 (Unix)
    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: X-PINGOTHER
    Access-Control-Max-Age: 1728000
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 0
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Content-Type: text/plain
    

    更新

    如 cmets 中所述,OPTION 响应的 Access-Control-Allow-Headers 缺少最后一个“s”。

    【讨论】:

    • 它仍然对我不起作用。我编辑了这个问题,并提供了有关我所做工作的更多信息。
    • 您需要像我引用的示例一样响应 OPTIONS。确保您有适当的 Access-Control-Allow-* 标记,以及对 OPTIOINS 的响应中的 200 OK。您可以将 Content-Type 保持为 text/plain。只是在我的答案中添加的 MDN 链接中的“预检”主题
    • 这就是我正在做的事情。我第二次编辑了这个问题,包含了 Firefox 发送和接收的标题的屏幕截图。我启用了 CORS,它运行良好......直到我添加了一个自定义 http 标头。
    • 伙伴,应该是 Access-Control-Allow-Headers。您缺少最后一个“s”。 - developer.mozilla.org/en/docs/HTTP/…
    • 另外,您是否也可以在 text/plain 的响应中设置 Content-Type。不确定这是否真的有影响,但将其保留为 json 在语义上是不正确的,因为您不会在响应中返回任何 json
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2017-08-13
    相关资源
    最近更新 更多