繁体   English   中英

对 Firebase Cloud Functions (Spark Tier) 中外部 API 的 HTTP 请求被拒绝

[英]HTTP request to an external API in Firebase Cloud Functions (Spark Tier) refused

我正在尝试从 Web 调用外部资源,并使用 NodeJS Client V2 和 Cloud Functions 将结果加载到 Dialogflow 中。

我已经尝试了这段代码的多种组合,使用了 Promise、外部函数等。没有运气。

测试1

function myIntent(conv) {
            // console.log('conv ', conv)

            const config ={
                "headers": {'X-App-Token': dataSFAPITOken},
                "Content-Type": "application/json"
            }
            const url = "http://data.sfgov.org/resource/cuks-n6tp.json";
            return new Promise((resolve, reject) => {

                axios
                    .get(url)
                    .then(response => {
                        console.log(response);
                        conv.ask('I got your data back')
                        return resolve(response)
                    })
                    .catch(error => {
                        console.log(error);
                        conv.ask('Sorry! Something went wrong')
                        return reject(error)
                    });
            })

    }
 app.intent('My Intent', myIntent);  
 exports.myAgent = functions.https.onRequest(app);

错误

这是我在调用myIntent后在 Cloud Functions Dashboard 上得到的错误。

{ Error: getaddrinfo ENOTFOUND data.sfgov.org data.sfgov.org:80
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'data.sfgov.org',
  host: 'data.sfgov.org',
  port: 80,
  config: 
   { adapter: [Function: httpAdapter],
     transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     headers: 
      { Accept: 'application/json, text/plain, */*',
        'User-Agent': 'axios/0.18.0' },
     method: 'get',
     url: 'http://data.sfgov.org/resource/cuks-n6tp.json',
     data: undefined },
  request: 
   Writable {
     _writableState: 
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        decodeStrings: true,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     domain: null,
     _events: 
      { response: [Function: handleResponse],
        error: [Function: handleRequestError] },
     _eventsCount: 2,
     _maxListeners: undefined,
     _options: 
      { protocol: 'http:',
        maxRedirects: 21,
        maxBodyLength: 10485760,
        path: '/resource/cuks-n6tp.json',
        method: 'get',
        headers: [Object],
        agent: undefined,
        auth: undefined,
        hostname: 'data.sfgov.org',
        port: null,
        nativeProtocols: [Object],
        pathname: '/resource/cuks-n6tp.json' },
     _redirectCount: 0,
     _requestBodyLength: 0,
     _requestBodyBuffers: [],
     _onNativeResponse: [Function],
     _currentRequest: 
      ClientRequest {
        domain: null,
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        upgrading: false,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedHeader: {},
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Object],
        connection: [Object],
        _header: 'GET /resource/cuks-n6tp.json HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.18.0\r\nHost: data.sfgov.org\r\nConnection: close\r\n\r\n',
        _headers: [Object],
        _headerNames: [Object],
        _onPendingData: null,
        agent: [Object],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path: '/resource/cuks-n6tp.json',
        _ended: false,
        _redirectable: [Circular],
        parser: null },
     _currentUrl: 'http://data.sfgov.org/resource/cuks-n6tp.json' },
  response: undefined }  

测试2

const url = "data.sfgov.org";
var options = {
    protocol:'http:',
    host: url,
    port : 8080,
    path:'/resource/cuks-n6tp',
    headers: {
        'X-App-Token': dataSFAPITOken,
        "Content-Type": "application/json"
    }
};
http.get(options, (http_res) => {
    // initialize the container for our data
    var data = "";

    // this event fires many times, each time collecting another piece of the response
    http_res.on("data", (chunk) =>{
        // append this chunk to our growing `data` var
        data += chunk;
    });

    // this event fires *one* time, after all the `data` events/chunks have been gathered
    http_res.on("end", () => {
        // you can use res.send instead of console.log to output via express
        console.log(data);
    });
});

这里是链接到官方文档这里

令人疯狂的是,下面是浏览器上的类似实现,并且可以正常工作。 事实上,我不需要 API 密钥来查询数据。 我可以简单地复制/粘贴链接。

$.ajax({
    url: "https://data.sfgov.org/resource/cuks-n6tp.json",
    type: "GET",
    data: {
      "$limit" : 50,
      "$$app_token" : "APPTOKEN"
    }
}).done(function(data) {
  // alert("Retrieved " + data.length + " records from the dataset!");
  console.log(data);
  document.getElementById('data').innerHTML = JSON.stringify(data, null,2)
});

但由于某些原因,我无法使其与 Dialogflow NodeJS Client V2 一起使用。 我很确定在 V1 中,我可以让它工作。

我迁移到 V2 有点痛苦。 请帮忙。

谢谢。

Firebase Cloud Functions 上的免费Spark计划不允许调用 Google 以外的域。

您需要升级到其中一种付费计划,例如FlameBlaze计划,这需要存档信用卡。 但是,对于使用量较低的情况,您无需为Blaze

下图显示了SparkFlameBlaze 请注意Google services only适用于SparkGoogle services only https://firebase.google.com/pricing/

在此处输入图片说明

2020 年 11 月更新

请注意, Flame计划不再可用。 因此,如果您想要外部访问,则需要使用Blaze计划。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM