Node.js 仅角度资源请求上缺少CORS标头

Node.js 仅角度资源请求上缺少CORS标头,node.js,express,cors,Node.js,Express,Cors,我有一个在本地主机上运行的工作节点/express后端。我正在构建一个需要从goodreads api获取数据的项目应用程序。当我执行请求时,我得到: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.goodreads.com/book/title.json?author=Arthur+Conan+Doyle&key=[m

我有一个在本地主机上运行的工作节点/express后端。我正在构建一个需要从goodreads api获取数据的项目应用程序。当我执行请求时,我得到:

Cross-Origin Request Blocked: 
The Same Origin Policy disallows reading the remote resource at 
https://www.goodreads.com/book/title.json?author=Arthur+Conan+Doyle&key=[my_key]&title=Hound+of+the+Baskervilles. 
(Reason: CORS header 'Access-Control-Allow-Origin' missing).1 <unknown>
我通过ng click调用fetch,所有操作都正常执行,除了我得到CORS错误。谁能给我指出正确的方向吗?我是angular的新手,我怀疑我的资源请求或配置中存在问题,但我似乎无法在文档或其他stackoverflow问题中找到解决问题的答案

更新3:这不是本地主机问题。我试着将它推到我的域中,并使用一个简单的按钮来运行对OpenBooksAPI的xhr请求,但问题变得更糟了。它是通过Openshift托管的,现在“Allow-Control-Access-x”头文件甚至对于我服务器上的其他文件也不存在了。真的开始把我的头撞到墙上了。我正在删除Angular标签,因为它与Angular无关

更新2:我在Chrome中安装了“允许控制允许原点”扩展后,它开始工作。我的问题是我在本地主机上运行这个吗?还是有别的事情发生了?在没有扩展名的情况下,仍无法设置标头

更新:我从早上8点就开始做这件事了,但还是不走运。我已经尝试过使用Angular的$http和Javascript的xhr重写请求,但每个方法都有相同的问题。正如我所说,必要的头信息可以从我服务器上的文件中获得,但当我向其他站点发出请求时,头信息会中断

我开始认为这可能不是一个角度的问题,但我真的没有线索。为了安全起见,以下是我添加到Express中以启用CORS的代码,包括app.use,以便您了解我将其命名的位置:

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Content-Length");
    res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    res.header("Access-Control-Allow-Credentials", "true");
    next();
});
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
编辑:以下是API请求的标题:

请求头

Host: www.goodreads.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101     Firefox/40.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:3000/
Origin: http://localhost:3000
Connection: keep-alive
响应头

Cache-Control: max-age=0, private, must-revalidate
Content-Encoding: gzip
Content-Length: 686
Content-Type: application/json; charset=utf-8
Date: Wed, 02 Sep 2015 17:20:35 GMT
Etag: "a2be782f32638d2a435bbeaf4b01274a-gzip"
Server: Server
Set-Cookie: csid=BAhJIhg1MzgtNTk4NjMzNy0wNzQ4MTM5BjoGRVQ%3D--afed14b563e5a6eb7b3fa9005de3010474230702; path=/; expires=Sun, 02 Sep 2035 17:20:33 -0000
locale=en; path=/
_session_id2=fd45336b8ef86010d46c7d73adb5f004; path=/; expires=Wed, 02 Sep 2015 23:20:35 -0000; HttpOnly
Status: 200 OK
Vary: Accept-Encoding,User-Agent
X-Content-Type-Options: nosniff, nosniff
X-Frame-Options: ALLOWALL
X-Request-Id: 1K8EJWG30GWDE4MZ4R5K
X-Runtime: 2.277972
X-XSS-Protection: 1; mode=block
来自我的服务器的.js文件的标题:

请求

Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101   Firefox/40.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://localhost:3000/
Cookie: _ga=GA1.1.1924088292.1439681064; connect.sid=s%3AB4O0Up9WF5iqkfky__I0XCiBD2aMATlq.gbJUC9GseqnJvRTEIbcwxD6cwFQeL7ljNScURCJ5As0
Connection: keep-alive
If-Modified-Since: Wed, 02 Sep 2015 17:08:40 GMT
If-None-Match: W/"886-14f8f0828c1"
Cache-Control: max-age=0
答复:

Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=0
Connection: keep-alive
Date: Wed, 02 Sep 2015 17:20:30 GMT
Etag: W/"886-14f8f0828c1"
Last-Modified: Wed, 02 Sep 2015 17:08:40 GMT
X-Powered-By: Express
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept

我猜这个问题暴露了我的无知,但也许这会帮助其他像我这样的CORs新手。在获得了一份运行中的CORs副本并使用flickrapi完成了第一个示例后,我终于解决了这个问题

我的问题与后端、Angular、jQuery的.ajax方法或xhr无关。我所有的请求格式都正确问题是,我尝试使用的API在其服务器上没有启用CORs。O.O我将数据类型更改为jsonp后,一切都进行了

无论如何,对于像我这样的新手来说,如果你遇到这个问题,这里有一些建议可以帮助你:

1。不要假设您使用的API已启用CORs

我不知道为什么,但我盲目地选择了两个没有启用CORs的API,这就是引起我大惊小怪的原因。我以前从未遇到过这个问题,因为我使用API所做的工作总是来自像Flickr这样启用CORs的大公司。如果他们没有在服务器上设置Access Control Allow Origin,您可以请求他们启用它,同时使用JSONP

如果API在最后有一个回调选项,那么这是一个好迹象,您应该使用JSONP处理您的请求。JSONP的工作原理是将请求包装在回调中,并利用脚本标记的一个特性。脚本可以从任何域中提取其他脚本,因此它可以作为获取数据的黑客。这里有一个很好的链接帮助了我

2。检查响应标题

我被这个欺骗了,但请记住,您对外部API的请求上的响应头是来自他们的服务器的响应,而不是您的响应。无论服务器上是否启用了CORs,您都是在向其他人发出请求,并且浏览器会在请求头中将您的信息自动发送给他们。记住,出于安全考虑,所有这些检查都是由浏览器完成的,因此它在请求端根据ajax调用为您完成繁重的工作。如果响应头中没有显示访问控制内容,则它们没有启用CORs。如果您在前端工作并请求其他人的数据,您对此无能为力。使用JSONP,您的问题(可能)就会消失

对我来说,这场惨败是因为我把来自我服务器的响应和来自他们服务器的响应搞混了。我在自己的服务器上正确地启用了CORs,但我认为它没有将原始信息附加到请求头上,这就是为什么它在响应头中不存在的原因。实际上,一切都正常工作,但API服务器没有启用它

就这样度过了一天,却学到了很多教训。希望我浪费的时间能帮助其他人解决CORs问题。请注意,我的问题与堆栈无关,因此无论您如何提出请求,如果遇到CORs问题,检查响应头都是第一步要采取的行动。之后,我建议调查请求本身是否存在错误


请查看上面的那本书或同一作者的此链接,以获得更多帮助,尤其是在涉及非简单请求时。

您可以发布API请求的标题吗?感谢您的阅读,Fred。我根据您的请求添加了标题信息。
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=0
Connection: keep-alive
Date: Wed, 02 Sep 2015 17:20:30 GMT
Etag: W/"886-14f8f0828c1"
Last-Modified: Wed, 02 Sep 2015 17:08:40 GMT
X-Powered-By: Express
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept