尝试通过 Google Cloud Functions 托管此 Express 应用

Mik*_*Kim 0 javascript node.js express firebase google-cloud-functions

所以..从这个Youtube教程:https://www.youtube.com/watch?v =NA21dUBfJhw&list=PL4cUxeGkcC9gcy9lrvMJ75z9maRw4byYp&index=33 我得到了一些“doto-list”的代码。问题是教程人员只进行了本地托管,而我正在尝试通过 Firebase 将其实际托管在实际网页上。所以我所做的就是在顶部添加 constfunctions = require('firebase-functions') 并添加exports.app =functions.https.onRequest((request,response) => {response.send("Hello from Firebase!" )在底部,我在实际网页上得到的唯一结果是“Hello from Firebase!”。有没有办法让整个“todo-list”程序在我的实际网页上运行?

索引.js

const functions = require('firebase-functions');
var express = require('express');
var app = express();

var todoController = require('./todoController');
app.set('view engine', 'ejs');

app.use(express.static('./'));

todoController(app);



exports.app = functions.https.onRequest((request, response) => {
    response.send("Hello from Firebase!");
});
Run Code Online (Sandbox Code Playgroud)

待办事项.ejs

<html>
      <head>
        <title>Todo List</title>
        <script
        src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256- 
        CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous"></script>
        <script src="./assets/todo-list.js"></script>
        <link href="./assets/styles.css" rel="stylesheet" 
         type="text/css">
      </head>
      <body>
        <div id="todo-table">
          <form>
            <input type="text" name="item" placeholder="Add new 
             item..." required />
            <button type="submit">Add Item</button>
          </form>
          <ul>

                  <% for(var i=0; i < todos.length; i++){ %>
                    <li><%= todos[i].item %></li>
                  <% } %>

          </ul>
        </div>

      </body>


    </html>
Run Code Online (Sandbox Code Playgroud)

todoController.js

var bodyParser = require('body-parser');

var data = [{item: 'get milk'}, {item: 'walk dog'}, {item: 'kick 
some coding ass'}];
var urlencodedParser = bodyParser.urlencoded({extended: false});

module.exports = function(app) {

app.get('/todo', function(req, res){
    res.render('todo', {todos: data});

});

app.post('/todo', urlencodedParser, function(req, res){
    data.push(req.body);
    res.json(data);
});


app.delete('/todo/:item', function(req, res){
    data = data.filter(function(todo){
        return todo.item.replace(/ /g, '-') !== req.params.item;
    });
    res.json(data);
});

};
Run Code Online (Sandbox Code Playgroud)

todo-list.js

$(document).ready(function(){

    $('form').on('submit', function(){

        var item = $('form input');
        var todo = {item: item.val()};

        $.ajax({
          type: 'POST',
          url: '/todo',
          data: todo,
          success: function(data){
            //do something with the data via front-end framework
            location.reload();
          }
        });

        return false;

    });

    $('li').on('click', function(){
        var item = $(this).text().replace(/ /g, "-");
        $.ajax({
          type: 'DELETE',
          url: '/todo/' + item,
          success: function(data){
            //do something with the data via front-end framework
            location.reload();
          }
        });
    });

  });
Run Code Online (Sandbox Code Playgroud)

编辑:原来只要我删除response.send("Hello from Firebase!"); 只需使用exports.app=functions.https.onRequest(app);,它就可以工作...这意味着response.send("Hello from Firebase!); 使这段代码不起作用。知道为什么吗?

d_s*_*hiv 6

您的原始设置不起作用,因为快速应用程序(使用express()调用创建)从未启动。快速应用程序必须调用app.listen(portNum)来启动服务器并开始接受传入连接。然而,这不是云函数的运作方式。不存在“启动服务器并等待客户端请求”的方法。相反,在云函数方法中,当收到请求时,会生成 JS 文件/项目,并在内部触发请求。您的应用程序持续侦听传入连接的想法根本不适用。

现在来看看有效的方法!

exports.app=functions.https.onRequest(app);
Run Code Online (Sandbox Code Playgroud)

如果您注意到,在您的原始代码中,functions.https.onRequest正在接受一个使用两个参数request, 和调用的函数response。这些对象基本上分别是http.IncomingMessagehttp.serverResponse类的实例。NodeJS 在内部使用一对这样的对象来表示所有 http 请求。巧合的是,当 Express 应用程序收到来自客户端的 http 请求时,它也是从这两个对象开始的。基于这两个对象,创建了一对更丰富的 Express Request 和 Response 对象,并通过中间件链进行传播。

现在,当您将appExpress 应用程序传递给 时functions.https.onRequest,firebase 系统基本上会将您视为app一个接受http.IncomingMessage对象和http.serverResponse对象作为参数的函数。这是expressJS 的一个未记录的功能,它将应用程序(存储在app此处的引用中)作为函数调用IncomingMessage,并ServerResponse分别提供第一个和第二个参数的实例,其行为就像底层服务器接收到http 请求一样。请求和响应在初始处理以及中间件链中运行,就像快递服务器直接接收的任何请求一样。这可以用在极少数情况下,即用户需要混合使用多个框架或无法显式启动服务器,但可以通过其他方式访问请求和响应对象。就像在这个场景中一样。

事实上,每次您调用云函数时,Firebase 函数框架都会调用存储在app引用中的 Express 应用程序作为函数,而您的中间件会完成其余的工作。