请求的资源缺少 'Access-Control-Allow-Origin' 头部错误。

113

我正在尝试获取一家新闻网站的新闻源。我想使用谷歌的Feed API将Feedburner提供的新闻源转换为JSON格式。以下URL将以JSON格式返回来自该源的10篇文章。http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&q=http://feeds.feedburner.com/mathrubhumi

我使用了以下代码来获取上述URL的内容。

$.ajax({
  type: "GET",
  dataType: "jsonp",
  url: "http://ajax.googleapis.com/ajax/services/feed/load",
  data: {
    "v": "1.0",
    "num": "10",
    "q": "http://feeds.feedburner.com/mathrubhumi"
  },
  success: function(result) {
    //.....
  }
});

但它没有运行并且我得到了以下错误

XMLHttpRequest 无法加载 http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&q=http%3A%2F%2Ffeeds.feedburner.com%2Fmathrubhumi。 在所请求的资源上不存在 'Access-Control-Allow-Origin' 标头。 因此,源 'http://localhost' 不允许访问。

我该如何修复此问题?


1
我在这里测试了你的代码,使用Chrome浏览器,结果符合预期。你尝试过使用“crossDomain:true”属性吗? - Daniel Loureiro
我在这里托管了你的代码:http://learnwithdaniel.com/test.html。看看能否无错误打开。如果没有错误,问题就出在你的服务器上。 - Daniel Loureiro
很好。所以它与您的浏览器请求此HTML时服务器发送的标头有关。检查“CORS标头”。 - Daniel Loureiro
这里同样涉及到GoDaddy API。 - Gilson Gilbert
这个问题不是重复的吗?https://dev59.com/H2Ij5IYBdhLWcg3wpmoH 更重要的是,另一个问题有更清晰/更全面的答案。 - Nate Anderson
这个回答解决了你的问题吗?在Chrome中禁用同源策略 - Michael Freidgeim
12个回答

115
如果你使用Google Chrome浏览器,你可以通过一个扩展程序进行黑客攻击。
你可以找到一个Chrome扩展程序,它可以即时地修改应用程序中的CORS头。显然,这只适用于Chrome浏览器,但我喜欢它不需要在任何地方进行更改就可以使用。
你可以在本地机器上调试你的应用程序(如果在生产环境中一切正常)。
注意:如果URL失效,该扩展名为Access-Control-Allow-Origin: *。我建议你在不处理你的东西时禁用此扩展程序,因为例如YouTube无法与此扩展程序配合工作。

这对我也绝对有效!我想插件的开发者已经更新了它,以适应手动输入特定URL而不是适用于所有内容,我访问了YouTube和其他网站,它完全正常运行。无论如何,非常感谢。 - Kingston Fortune
1
这是开发过程中的测试内容,用户不会在浏览器中添加插件。 - Abdulmoiz Ahmer
看起来那个扩展程序不再可用,至少在那个URL上是这样。然而,这个扩展程序似乎可以使用:https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf - Gordon
1
但是这个扩展程序在做什么?你知道有没有开源版本或者怎样编写一个修改头文件的扩展程序吗?你可能不想(好吧,我不想)运行一个完全访问URL和数据而不知道它在做什么的扩展程序。如果扩展程序易手、已经恶意等,那似乎是一个非常糟糕的想法。 编辑: 下面提到的那个开源的,供参考。 - ruffin
@ruffin 感谢您指出这个问题!此外,值得一提的是,这个开源的 Chrome 插件 CORS Unblock 也可在 Firefox 和 Microsoft Edge 上使用。 - gaborous
在浏览器中使用“localhost”而不是“127.0.0.1”,解决了我的CORS问题。 - m_ocean

90

我认为这很可能是因为Chrome不支持localhost通过Access-Control-Allow-Origin--请看Chrome问题详情

要让Chrome在标题中发送Access-Control-Allow-Origin,只需将您的/etc/hosts文件中的localhost别名到另一个域,例如:

127.0.0.1   localhost yourdomain.com

如果您使用 yourdomain.com 而不是 localhost 访问您的脚本,则调用应该成功。


谢谢。我遇到了这个问题,切换到IE Edge后,我看到了我的服务器代码中被Chrome的本地主机拒绝所掩盖的潜在错误。 - Aluan Haddad
8
我也无法使用。也许Chrome的更新封堵了这个“漏洞”? - Marty C.
3
这里也没有帮助。我的网站已经按这种方式设置,但我有一个很大的区别。我正在使用不同的端口。我相信如果使用相同的端口,它会起作用。当然,HTTP和HTTPS是不同的端口,所以可能会引起一些问题。我的网站不是特定的HTTPS,但我正在尝试访问同一域上不同于80的端口的某些内容。 - Jerry Dodge
如果API被Chrome扩展访问,应该怎么办? - viveksinghggits

10

尝试这个 - 通过设置头文件来设置Ajax调用,如下所示:

尝试这个 - 通过设置头文件来设置Ajax调用,如下所示:

var uri = "http://localhost:50869/odata/mydatafeeds"
$.ajax({
    url: uri,
    beforeSend: function (request) {
        request.setRequestHeader("Authorization", "Negotiate");
    },
    async: true,
    success: function (data) {
        alert(JSON.stringify(data));
    },
    error: function (xhr, textStatus, errorMessage) {
        alert(errorMessage);
    }                
});

然后使用以下命令行打开Chrome来运行您的代码:

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

4

跨域资源共享(CORS)解锁在Chrome 78上效果很好

[COrs unb] [1] https://chrome.google.com/webstore/detail/cors-unblock/lfhmikememgdcahcdlaciloancbhjino

这是一个名为"CORS解锁"的谷歌浏览器插件。

概述:启用后,通过将“Access-Control-Allow-Origin:*”标头附加到本地和远程Web请求中,消除CORS错误。

该扩展程序通过为浏览器接收到的每个请求提供自定义的“access-control-allow-origin”和“access-control-allow-methods”标头,提供对XMLHttpRequest和fetch方法的控制。用户可以从工具栏按钮切换扩展程序的开关状态。要修改如何更改这些标头,请使用右键单击上下文菜单项。您可以自定义允许的方法。默认选项是允许“GET”,“PUT”,“POST”,“DELETE”,“HEAD”,“OPTIONS”,“PATCH”方法。您还可以要求扩展程序在服务器已填充这些标头时不要覆盖这些标头。


正如上面的评论者所指出的那样,这个插件是开源的,考虑到这种插件可以访问所有URL,因此透明度是受欢迎的。它也可在Firefox和Microsoft Edge上使用。不错的发现!谢谢你的分享! - gaborous

2

另一种解决方法是在包含'@SpringBootApplication'的主应用程序类中添加以下代码,并在需要时重新启动服务器。这对我有效。

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        corsConfiguration.setAllowedHeaders(Arrays.asList("Origin","Access-Control-Allow-Origin",
                "Content-Type","Accept","Authorization","Origin,Accept","X-Requested-With",
                "Access-Control-Request-Method","Access-Control-Request-Headers"));
        corsConfiguration.setExposedHeaders(Arrays.asList("Origin","Content-Type","Accept","Authorization",
                "Access-Control-Allow-Origin","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
        corsConfiguration.setAllowedMethods(Arrays.asList("GET","PUT","POST","DELETE","OPTIONS"));
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
        
    }

1

提供信息,我注意到这个问题在jQuery文档中有所提及:

由于浏览器安全限制,大多数“Ajax”请求受到同源策略的限制;请求无法成功从不同的域、子域、端口或协议中检索数据。

像@thanix一样更改hosts文件对我没有用,但是@dkruchok提到的扩展程序解决了这个问题。


0

Chrome 不允许您集成两个不同的 localhost,这就是为什么我们会收到此错误的原因。您只需从 nuget 管理器中包含 Microsoft Visual Studio Web Api 核心包,并在 WebApi 项目的 WebApiConfig.cs 文件中添加两行代码即可。

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

然后全部完成。


显然,这仅适用于Dotnet Core后端。 - alas

0

对于开发,您可以使用https://cors-anywhere.herokuapp.com,对于生产环境最好设置自己的代理。

async function read() {
   let r= await (await fetch('https://cors-anywhere.herokuapp.com/http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&q=http://feeds.feedburner.com/mathrubhumi')).json();
   console.log(r);
}

read();


0
如果你使用Express,请在使用cors后添加路由。
app.use(cors()); app.use('/posts', postRoutes);

0

另一种方法是使用CORS代理,您只需要在URL前添加https://cors-anywhere.herokuapp.com/,这样您的URL将变成https://cors-anywhere.herokuapp.com/http://ajax.googleapis.com/ajax/services/feed/load

代理服务器从上面的URL接收http://ajax.googleapis.com/ajax/services/feed/load。然后它发出请求以获取该服务器的响应。最后,代理将

Access-Control-Allow-Origin: *

应用于原始响应。

这个解决方案非常好,因为它在开发和生产中都可以使用。总之,您正在利用同源策略仅在浏览器到服务器通信中实现的事实。这意味着不必在服务器到服务器通信中执行它!

您可以在Medium上阅读有关解决方案的更多信息3种解决CORS错误的方法


1
截至2021年1月31日,由于滥用,cors-anywhere已被限制使用,并且通常不应在生产中使用,除非您每天的请求次数非常有限。https://github.com/Rob--W/cors-anywhere/issues/301 - Miqi180

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接