Access-Control-Allow-Origin 不起作用 Google Cloud Functions GCF
Posted
技术标签:
【中文标题】Access-Control-Allow-Origin 不起作用 Google Cloud Functions GCF【英文标题】:Access-Control-Allow-Origin not working Google Cloud Functions GCF 【发布时间】:2017-06-27 16:07:48 【问题描述】:我在这里感觉自己像个新手,但我正在尝试从浏览器运行一个简单的 AJAX 请求以访问 GCF,Chrome 正在报告:
XMLHttpRequest 无法加载 https://us-central1-bustling-opus-830.cloudfunctions.net/Authenticate。 请求中不存在“Access-Control-Allow-Origin”标头 资源。原点 'https://beast.reachboarding.com.au' 因此不是 允许访问。
我有一个名为 Authenticate 的函数(如上所示),它使用了一个名为:
bustling-opus-830.appspot.com
我使用 gsutil 通过以下 JSON 文件设置 CORS:
[
"origin": ["https://beast.localdev.com.au","*"],
"responseHeader": ["Content-Type"],
"method": ["GET", "HEAD", "DELETE", "OPTIONS"],
"maxAgeSeconds": 3600
]
使用以下命令:
gsutil cors set cors.json gs://bustling-opus-830.appspot.com/
然后从对应的get命令中得到如下输出:
gsutil cors get gs://bustling-opus-830.appspot.com/
["maxAgeSeconds": 3600, "method": ["GET", "HEAD", "DELETE", "OPTIONS"], "origin": ["https://beast.localdev.com.au", "*"], "responseHeader": ["Content-Type"]]
我使用的是您在创建新函数时提供的默认示例代码,如下所述:
/**
* Responds to any HTTP request that can provide a "message" field in the body.
*
* @param !Object req Cloud Function request context.
* @param !Object res Cloud Function response context.
*/
exports.helloWorld = function helloWorld(req, res)
// Example input: "message": "Hello!"
if (req.body.message === undefined)
// This is an error case, as "message" is required.
res.status(200).send('No message defined!');
else
// Everything is okay.
console.log(req.body.message);
res.status(200).send(req.body.message);
;
还有一个带有以下 javascript 的简单 html:
$.ajax(
url: "https://us-central1-bustling-opus-830.cloudfunctions.net/Authenticate",
type: "POST",
data:
message: 'Testing'
,
dataType: 'json',
success: function (response)
console.log(response);
,
error: function (xhr, status)
console.log(xhr);
);
导致错误的原因。
在我的 DEV 控制台中,我可以看到网络请求通过。以下是我得到的 HTTP 响应标头:
cache-control:private
content-encoding:gzip
content-length:27
content-type:text/html; charset=utf-8
date:Wed, 08 Feb 2017 03:45:50 GMT
etag:W/"7-274e639a"
function-execution-id:azc1zqfb1tq8
server:Google Frontend
status:200
vary:Accept-Encoding
x-cloud-trace-context:70e08d634a9644c32530326de0471a64;o=1
x-cloud-trace-context:70e08d634a9644c32530326de0471a64
x-powered-by:Express
我本来希望在响应标头中看到 Access-Control-Allow-Origin 标头,表明它允许 * 但我绝对没有看到它。
但疯狂的是,当我查看 Network 项目并单击 Response 时,我得到:
Testing
这表明所有事情都是平等的,它实际上运行了!
如果之前已经回答过这个问题,我深表歉意,但我已经搜索了许多不同的关键字,但似乎没有任何东西可以解决我的问题。我认为重新审视这个问题(以及一些体面的专业知识)会有所帮助。
提前致谢!
【问题讨论】:
gsutil 命令gsutil cors set cors.json gs://bustling-opus-830
是否正确,或者您已经确定gsutil cors set cors.json gs://bustling-opus-830.appspot.com/
应该实现相同的功能?我问是因为cloud.google.com/storage/docs/… 的文档只使用了不合格的形式gsutil cors set cors-json-file.json gs://example
我相信这两个命令在语法上是相同的。我看到的唯一区别是 JSON 文件的名称。我使用了 cors.json,示例中有 cors-json-file.json。是这个意思吗?
不,我的意思是gs://bustling-opus-830.appspot.com/
vs gs://bustling-opus-830
啊,明白了。我刚刚尝试不使用 .appspot.com 并收到“NotFoundException:404”消息。然后我尝试了 gsutil cors get gs://bustling-opus-830 并得到“BucketNotFoundException:404 gs://bustling-opus-830 存储桶不存在”。所以我假设谷歌文档只是对存储桶的引用,而不是绝对路径。感谢您一直以来的帮助。还有其他想法吗?您是否能够通过 AJAX 成功发布到 GCF?
【参考方案1】:
您的前台 (HTTP) Google Cloud Function 需要在对 AJAX 客户端请求的响应中设置适当的 CORS 标头。 HTTP Functions 的请求和响应参数具有与对应的 ExpressJS 对象等效的属性,可用于设置 CORS 标头并根据需要响应预检请求。
例如:
exports.Authenticate = function Authenticate (req, res)
//set JSON content type and CORS headers for the response
res.header('Content-Type','application/json');
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
//respond to CORS preflight requests
if (req.method == 'OPTIONS')
res.status(204).send('');
//continue function ...
;
上面的标题和逻辑应该被修改以反映你的服务的特定需求,但希望能帮助你开始。
【讨论】:
瑞恩你死定的传奇!我不敢相信这是多么简单。我添加了标题并点击刷新,它立即按预期执行。非常感谢! 你是我的救星。我花了一整天的时间试图解决这个问题,这是唯一解决它的方法。【参考方案2】:您也可以按照 Google 的建议使用 cors
包来解决此问题。事实上,他们也在自己的示例代码中使用了这一点。检查此example。
这是代码 -
const cors = require('cors')(
origin: true,
);
//Your code here
//Use the following function instead of just res.send. return keyword is not compulsory here
return cors(req, res, () =>
res.send();
);
【讨论】:
【参考方案3】:如果您仍然对答案感兴趣,我实际上写了一篇关于如何使用 Express 中间件处理该问题的博文:https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html。
【讨论】:
此链接现在似乎已损坏。以上是关于Access-Control-Allow-Origin 不起作用 Google Cloud Functions GCF的主要内容,如果未能解决你的问题,请参考以下文章