Попытка разместить это экспресс-приложение через Google Cloud Functions - PullRequest
0 голосов
/ 11 июня 2019

так .. из этого урока Youtube: https://www.youtube.com/watch?v=NA21dUBfJhw&list=PL4cUxeGkcC9gcy9lrvMJ75z9maRw4byYp&index=33 Я получил некоторый код для «списка дел». Проблема в том, что учитель делал только локальный хостинг, и я пытаюсь разместить его на реальной веб-странице через Firebase. поэтому я добавил в начало const functions = require ('firebase-functions') и добавил export.app = functions.https.onRequest ((request, response) => { response.send («Привет из Firebase!») внизу, и единственный результат, который я получаю на настоящей веб-странице, - «Привет из Firebase!». Есть ли способ заставить всю программу 'todo-list' работать на моей реальной веб-странице?

index.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!");
});

todo.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>

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

};

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

  });

edit: Оказывается, пока я удаляю response.send («Привет из Firebase!»); и просто используйте exports.app = functions.https.onRequest (app) ;, это работает ... что означает response.send («Привет из Firebase!); делает этот код неработающим. Любая идея, почему?

»

1 Ответ

2 голосов
/ 11 июня 2019

Ваша первоначальная настройка не работает, потому что экспресс-приложение (созданное с помощью вызова express()) никогда не запускается. Экспресс-приложение должно вызвать app.listen(portNum), чтобы запустить сервер и начать принимать входящие соединения. Это, однако, не так, как работают облачные функции. Не существует подхода «запусти сервер и жди запроса от клиента». Вместо этого в подходе облачных функций, когда запрос получен, файл / проект JS порождается, и запрос запускается изнутри. Идея вашего приложения, постоянно прослушивающего входящее соединение, просто не применима.

Теперь перейдем к подходу, который работает!

exports.app=functions.https.onRequest(app);

Если вы заметили, в исходном коде functions.https.onRequest принимал функцию, которая вызывается с двумя параметрами request и response. Эти объекты в основном являются экземплярами классов http.IncomingMessage и http.serverResponse соответственно. NodeJS внутренне представляет все http-запросы, используя пару таких объектов. По совпадению, когда экспресс-приложение получает запрос http от клиента, оно также запускается с этими двумя объектами. На основе этих двух создается пара гораздо более богатых объектов Express Request и Response, которые распространяются по цепочке промежуточного программного обеспечения.

Теперь, когда вы передаете app, Экспресс-приложение, в functions.https.onRequest, система Firebase в основном будет рассматривать вашу app как функцию, которая принимает объект http.IncomingMessage и объект http.serverResponse в качестве параметров. Это недокументированная особенность expressJS, которая вызывает приложение (хранится здесь в справочнике app) как функцию, предоставляющую экземпляры IncomingMessage и ServerResponse в качестве 1-го и 2-го параметров соответственно, ведет себя так, как если бы запрос http был получен базовым сервером. Запрос и ответ выполняются через начальную обработку, а также цепочку промежуточного программного обеспечения точно так же, как любой запрос, полученный непосредственно сервером экспресс-доставки. Это может быть использовано в редких сценариях, когда пользователю необходимо сочетание нескольких платформ или иным образом нельзя явно запустить сервер, но он может получить доступ к объектам запроса и ответа другими способами. Как в этом сценарии.

Действительно, каждый раз, когда вы вызываете вашу облачную функцию, инфраструктура функций Firebase будет вызывать экспресс-приложение, хранящееся в справочнике app, как функцию, а ваши промежуточные программы сделают все остальное.

...