Javascript 访问控制允许源站不工作谷歌云功能GCF

Javascript 访问控制允许源站不工作谷歌云功能GCF,javascript,node.js,ajax,cors,google-cloud-functions,Javascript,Node.js,Ajax,Cors,Google Cloud Functions,我觉得自己是个新手,但我正试图从浏览器运行一个简单的AJAX请求来访问GCF,Chrome正在报告: 无法加载XMLHttpRequest . 请求的服务器上不存在“Access Control Allow Origin”标头 资源。因此,源“”不是 允许访问 我有一个名为Authenticate(如上所示)的函数,它使用一个名为: bustling-opus-830.appspot.com 我使用gsutil使用以下JSON文件设置CORS: [{ "origin": ["https

我觉得自己是个新手,但我正试图从浏览器运行一个简单的AJAX请求来访问GCF,Chrome正在报告:

无法加载XMLHttpRequest . 请求的服务器上不存在“Access Control Allow Origin”标头 资源。因此,源“”不是 允许访问

我有一个名为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);
    }
});
这是导致错误的原因

在我的开发控制台中,我可以看到网络请求通过。下面是我得到的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头,以表明它允许*但我肯定没有看到它

但疯狂的是,当我查看网络项目并单击响应时,我得到:

Testing
这意味着所有的事情都是平等的,它实际上运行了

如果以前有人回答过这个问题,我很抱歉,但我已经搜索了很多不同的关键字,似乎没有任何东西能解决我的问题。我认为在这个问题上有一双新的眼睛(和一些像样的专业知识)会有所帮助

提前谢谢

您的前台(HTTP)Google Cloud函数需要在对AJAX客户端请求的响应中设置适当的CORS头。的请求和响应参数具有与相应的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 ...

};

上面的标题和逻辑应该进行修改,以反映您服务的特定需求,但希望能够帮助您入门。

如果您仍然对答案感兴趣,我实际上写了一篇关于如何使用Express middleware处理此问题的博文:。

您也可以使用
cors
包来解决此问题,正如谷歌推荐的那样。事实上,他们在自己的示例代码中也使用了这一点。看看这个。 这是守则-

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();
});

正确的gsutil命令是
gsutil cors set cors.json gs://busting-opus-830
,还是您已经确定
gsutil cors set cors.json gs://busting-opus-830.appspot.com/
应该实现同样的效果?我之所以这样问,是因为位于的文档只使用了非限定格式
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 bucket不存在”。因此我假设Google文档中的内容只是对bucket的引用,而不是绝对路径。谢谢你迄今为止的帮助。还有其他想法吗?你成功地通过AJAX发布到GCF了吗?Ryan,你这个死定了的传奇人物!我不敢相信这是多么愚蠢的简单。我添加了标题并点击刷新,它立即按预期执行。非常感谢你!你是我的救世主。我花了一整天的时间想弄明白,这是唯一能解决这个问题的方法。