AngularJS 没有检测到 Access-Control-Allow-Origin 标头?
Posted
技术标签:
【中文标题】AngularJS 没有检测到 Access-Control-Allow-Origin 标头?【英文标题】:AngularJS not detecting Access-Control-Allow-Origin header? 【发布时间】:2014-02-01 20:55:27 【问题描述】:我正在本地虚拟主机 (http://foo.app:8000) 上运行 Angular 应用程序。它正在使用 $http.post
向另一个本地 VirtualHost (http://bar.app:8000) 发出请求。
$http.post('http://bar.app:8000/mobile/reply', reply, withCredentials: true);
在 Chrome 开发者工具的 Network 选项卡中,我当然看到了 OPTIONS 请求,并且响应包括标题:
Access-Control-Allow-Origin: http://foo.app:8000
但是,POST 请求被取消并出现以下错误:
请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'http://foo.app:8000'。
有人经历过吗? Access-Control-Allow-Origin
标头非常明显地包含在 OPTIONS 请求的响应中,因此我无法终生弄清楚为什么 POST 正在执行标头丢失。
Access-Control-Allow-Credentials
也设置为true
。
【问题讨论】:
您在 OPTIONS 响应中看到 Access-Control-Allow-Methods 标头吗? 确实如此。允许所有方法。 【参考方案1】:而不是使用 $http.get('abc/xyz/getSomething') 尝试使用 $http.jsonp('abc/xyz/getSomething')
return
getList:function()
return $http.jsonp('http://localhost:8080/getNames');
【讨论】:
【参考方案2】:CROS 需要从服务器端解析。
根据要求创建过滤器以允许访问并在 web.xml 中添加过滤器
使用弹簧的示例:
过滤器类:
@Component
public class SimpleFilter implements Filter
@Override
public void init(FilterConfig arg0) throws ServletException
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException
HttpServletResponse response=(HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, resp);
@Override
public void destroy()
Web.xml:
<filter>
<filter-name>simpleCORSFilter</filter-name>
<filter-class>
com.abc.web.controller.general.SimpleFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>simpleCORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【讨论】:
【参考方案3】:如果你们在sails.js 中遇到这个问题,只需将您的cors.js 设置为包含授权作为允许的标题
/***************************************************************************
* *
* Which headers should be allowed for CORS requests? This is only used in *
* response to preflight requests. *
* *
***************************************************************************/
headers: 'Authorization' // this line here
【讨论】:
【参考方案4】:当您的请求中的参数错误时也会发生这种情况。就我而言,我正在使用向我发送消息的 API
“请求的资源上不存在'Access-Control-Allow-Origin'标头。因此不允许访问源'null'。响应的HTTP状态代码为401。”
当我使用 POST 请求登录时发送错误的用户名或密码。
【讨论】:
【参考方案5】:对于想要使用 Chrome 的用户,有一个解决方法。 This extension 允许您使用 AJAX 从任何来源请求任何站点,因为它会将 'Access-Control-Allow-Origin: *'
标头添加到响应中。
作为替代方案,您可以将此参数添加到 Chrome 启动器:--disable-web-security
。请注意,我只会将其用于开发目的,而不是用于正常的“网上冲浪”。参考见Run Chromium with Flags。
最后一点,通过安装第一段中提到的扩展,您可以轻松启用/禁用 CORS。
【讨论】:
一个额外的好处是,这个非常有用的插件也恰好阻止了 Facebook 的工作,所以如果你的软件开发工作流程与我的相似,你可能会在创纪录的时间内完成剩下的工作。 这是真的,@ChrisRae。 这个扩展似乎可以消除错误。但是,当我检查请求标头时,它会添加 Origin:evil.com。我不知道这是否有害或无关紧要。【参考方案6】:我正在使用 $http 服务从 angularjs 向在 http://localhost:8090/
上运行的 bottle 发送请求,我必须应用 CORS 否则我收到请求错误,例如“不存在‘Access-Control-Allow-Origin’标头在请求的资源上”
from bottle import hook, route, run, request, abort, response
#https://github.com/defnull/bottle/blob/master/docs/recipes.rst#using-the-hooks-plugin
@hook('after_request')
def enable_cors():
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT'
response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
【讨论】:
【参考方案7】:我遇到了同样的问题。对我来说,OPTIONS 请求会通过,但 POST 请求会说“已中止”。这让我相信浏览器根本没有发出 POST 请求。 Chrome 在请求标头中说“警告临时标头已显示”,但未显示响应标头。最后,我转向在 Firefox 上进行调试,这导致我发现我的服务器响应错误并且响应中没有 CORS 标头。 Chrome 实际上正在接收响应,但不允许响应显示在网络视图中。
【讨论】:
谢谢 - 你让我解决了我自己的问题。我有同样的症状。就我而言,我使用的是 Amazon API 网关并从 Chrome 中的 AngularJS 调用它。我错过了一个参数,与@tacticurv 建议的一样,但是当 OPTIONS 请求明显成功时,Chrome 暗示它由于 CORS 而从未发布过 POST。我发现的额外问题是 API 网关有用的“启用 CORS”按钮并不能完全发挥作用。它只在 200 个 OK 响应中添加了标头,而在 400 和 500 个错误响应中错过了它们。然后这些错误被 chrome 检查器遗漏了! @charltones 实际上,自从我发布该答案以来,我一直在使用chrome://net-internals/#events
来检测此类错误,而不是使用 Firefox。方便以后知道。实际上,我确实向 Chromium 发送了一个错误,并且修复了一段时间,但我认为他们将其恢复了。 code.google.com/p/chromium/issues/detail?id=343707【参考方案8】:
我今天刚遇到这个问题。事实证明,服务器上的一个错误(空指针异常)导致它无法创建响应,但它仍然生成了 200 的 HTTP 状态代码。由于 200 状态代码,Chrome 期望一个有效的响应。 Chrome 做的第一件事是寻找“Access-Control-Allow-Origin”标头,但没有找到。 Chrome 然后取消了请求,Angular 给了我一个错误。处理 POST 请求期间的错误是导致 OPTIONS 成功,但 POST 失败的原因。
简而言之,如果您看到此错误,可能是您的服务器在响应 POST 请求时根本没有返回任何标头。
【讨论】:
这基本上是我遇到的问题 - 感谢您的提醒。【参考方案9】:对于本地开发人员来说,这是 chrome 中的一个错误。尝试其他浏览器。然后它会工作。
【讨论】:
谢谢。在 Firefox 中运行良好。你有关于这个错误的更多信息吗? 不是真正的错误,而是出于安全原因。见:***.com/questions/3102819/… 我在其他浏览器中尝试过,它有效@_@ 为什么 chrome 如此卑鄙:( 当您准备部署应用程序以供更多受众使用时应该怎么做,大多数人使用 Chrome,处理此问题的正确方法是什么? 这不是一个解决方案!!!这与CORS有关,而不仅仅是浏览器……它是一个安全约束。您始终可以在您的服务器上启用 CORS。以上是关于AngularJS 没有检测到 Access-Control-Allow-Origin 标头?的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS - 在 n 分钟内没有检测到任何动作并进入默认状态
AngularJS 没有检测到 Access-Control-Allow-Origin 标头?