Access-Control-Allow-Origin不起作用Google Cloud Functions GCF

时间:2017-02-09 15:10:57

标签: javascript node.js ajax cors google-cloud-functions

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

  

XMLHttpRequest无法加载   https://us-central1-bustling-opus-830.cloudfunctions.net/Authenticate。   No' 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标头,表明它允许*但我绝对没有看到它。

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

Testing

这表明所有事情都是平等的,它实际上就跑了!

如果之前已经回答了这个问题,我很抱歉,但是我搜索了很多不同的关键字,似乎没有解决我的问题。我认为对这个问题(以及一些体面的专业知识)有一双新的眼光会有所帮助。

提前致谢!

3 个答案:

答案 0 :(得分:16)

您的前台(HTTP)Google Cloud功能需要在对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 ...

};

应修改上面的标题和逻辑以反映您服务的特定需求,但希望能帮助您开始使用。

答案 1 :(得分:2)

如果您仍然对答案感兴趣,我实际上写了一篇关于如何使用Express中间件处理该问题的博文:https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

答案 2 :(得分:2)

您还可以使用cors软件包修复此问题,这是Google推荐的。实际上,他们也在自己的示例代码中使用它。检查此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();
});