使用 CORS 测试 firebase HTTPS 调用

Posted

技术标签:

【中文标题】使用 CORS 测试 firebase HTTPS 调用【英文标题】:Testing firebase HTTPS call with CORS 【发布时间】:2017-10-28 19:07:20 【问题描述】:

我正在尝试为我的 firebase 云功能设置本地测试环境。但是,当我尝试对我的一个 HTTP 函数进行虚假调用时遇到了问题。

我的错误原因似乎是我使用了 CORS (npm)。当我删除 cors 并仅使用 response.status(200) 运行下面看到的函数“test”时,一切正常。但是当使用 cors(req,res) 包装时,我的测试失败并出现 TypeError: Cannot read property 'origin' of undefined。

我在这里做错了什么?

在 index.js 中 -->

exports.test = functions.https.onRequest((request, response) => 

cors(request, response, () => 
    response.status(200);
    response.send("test ok");
)

在我的 test.js 中

describe('Cloud Functions', () => 
    // [START stubConfig]
    var myFunctions, configStub, adminInitStub, functions, admin, cors;

    before(() => 
        // Since index.js makes calls to functions.config and admin.initializeApp at the top of the file,
        // we need to stub both of these functions before requiring index.js. This is because the
        // functions will be executed as a part of the require process.
        // Here we stub admin.initializeApp to be a dummy function that doesn't do anything.
        admin = require('firebase-admin');
        cors = require('cors')(
            origin: true
        );
        adminInitStub = sinon.stub(admin, 'initializeApp');
        // Next we stub functions.config(). Normally config values are loaded from Cloud Runtime Config;
        // here we'll just provide some fake values for firebase.databaseURL and firebase.storageBucket
        // so that an error is not thrown during admin.initializeApp's parameter check
        functions = require('firebase-functions');
        configStub = sinon.stub(functions, 'config').returns(
            firebase: 
                databaseURL: 'https://not-a-project.firebaseio.com',
                storageBucket: 'not-a-project.appspot.com',
            
            // You can stub any other config values needed by your functions here, for example:
            // foo: 'bar'
        );
        // Now we can require index.js and save the exports inside a namespace called myFunctions.
        // This includes our cloud functions, which can now be accessed at myFunctions.makeUppercase
        // and myFunctions.addMessage
        myFunctions = require('../index');
    );

    after(() => 
        // Restoring our stubs to the original methods.
        configStub.restore();
        adminInitStub.restore();
    );
    // [END stubConfig]


        describe('test', () => 
            it('should return status code 200', (done) => 

                // [START invokeHTTPS]
                // A fake request object, with req.query.text set to 'input'
                const req = ;
                // A fake response object, with a stubbed redirect function which asserts that it is called
                // with parameters 303, 'new_ref'.
                const res = 
                    status: (status) => 
                        assert.equal(status, 200);
                        done();
                    
                ;

                // Invoke addMessage with our fake request and response objects. This will cause the
                // assertions in the response object to be evaluated.
                myFunctions.test(req, res);
                // [END invokeHTTPS]


            )
        )



)

【问题讨论】:

【参考方案1】:

试试这个: 而不是使用const req = ; 使用:

const req = 
   headers:  origin: true ,
;

【讨论】:

【参考方案2】:

最后,带有 firebase 功能和 cors 的单元测试正在运行

你必须在响应中设置Header和GetHeader

 setHeader: (key, value) => ,
 getHeader: (value) => ,

测试

const test = require('firebase-functions-test')()

let myFunctions

beforeAll(() => 
  myFunctions = require('../src/index')
)

afterAll(() => 
  test.cleanup()
)

it('get', async () => 
  let request =  headers:  origins: true  

  const response = 
    setHeader: (key, value) => 
    ,
    getHeader: (value) => 
    ,
    status: (code) => 
      expect(code).toBe(200)
      return  send: (body) => 
        expect(body).toBe('ok')
      
      
    

  
  myFunctions.addLink(request, response)
)

索引

const functions = require('firebase-functions')
const cors = require('cors')(
  origin: true
)

exports.addLink = functions.https.onRequest((req, res) => 
  return cors(req, res, () => 
    res.status(200).send('ok')
  )
)

【讨论】:

origin: true,出错了【参考方案3】:

这是我使用 sinon 解决 cors 错误的方法

const res = ;

Object.assign(res, 
  status: sinon.stub().returns(res),
  end: sinon.stub().returns(res),
  json: sinon.stub().returns(res),
  setHeader: sinon.stub(),
  getHeader: sinon.stub(),
);

beforeEach(() => 
  Object.values(res).forEach(stub => stub.resetHistory());
);

然后,在您的测试中,您可以测试您的回答:

    cloudFunctions.testFunction( query:  text: 'foo'  , res);
    response = res.json.lastCall.args[0];

【讨论】:

【参考方案4】:

在您的请求中添加标头: origin: '*' ,并将 setHeader () 添加到响应中

const req = 
    origin: '*' 
;

const res = 
  status: (status) => 
      assert.equal(status, 200);
      done();
  
;

【讨论】:

origin: '*' 不起作用,因为 cors 在 firebase 云功能上需要 origin: true

以上是关于使用 CORS 测试 firebase HTTPS 调用的主要内容,如果未能解决你的问题,请参考以下文章

由于 CORS 限制,无法使用 firebase 在本地进行测试

从被 CORS 阻止的 Firebase 托管代码调用 Firebase 函数

未为 Firebase 云功能启用 Cors

如何在 firebase 函数环境中解决 CORS?

使用 Cloud Functions for Firebase 时出现 CORS 错误

云功能和 Firebase 的客户端 CORS 错误