Попытка разместить это экспресс-приложение через Google Cloud Functions

Итак... из этого туториала на Youtube: https://thewikihow.com/video_NA21dUBfJhw&list=PL4cUxeGkcC9gcy9lrvMJ75z9maRw4byYp&index=33 У меня есть код для «doto-list». Проблема в том, что парень-туториал делал только локальный хостинг, а я пытаюсь разместить его на реальной веб-странице через Firebase. поэтому я добавил const functions = require('firebase-functions') вверху и добавил exports.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!); заставлял этот код не работать. Есть идеи, почему?

Эта строка кода не будет работать: app.listen(5000, '127.0.0.1'). Вы не можете прослушивать некоторые порты в Cloud Functions. Если вы хотите запустить экспресс-приложение в Cloud Functions, используйте это в качестве примера: github.com/firebase/functions-samples/tree/master/….

Doug Stevenson 11.06.2019 17:38

Я удалил: app.listen(5000, '127.0.0.1'). до сих пор не работает. Я читал документацию, но она была очень длинной, и мне хотелось, чтобы я полностью переделал все это, и я помню, как размещал файл JavaScript в Cloud Functions в прошлом, просто добавив пару строк кода, таких как: const functions = require(' firebase-функции'); и exports.app = functions.https.onRequest((запрос, ответ) => { response.send("Привет из Firebase!"); }); и я не знаю, почему это работало нормально в прошлом (например, в прошлом месяце), но не сейчас.

Mike Kim 11.06.2019 18:31

Одна вещь, которую я заметил, это то, что в коде, который я написал в своем вопросе, облачные функции работают нормально и показывают результат «Привет из Firebase!» и я не получил никакого сообщения об ошибке. просто программа «todo» не отображалась на веб-странице (вероятно, потому, что что-то не было встроено, пока часть Firebase работала правильно).

Mike Kim 11.06.2019 18:51

Внимательно посмотрите на пример, на который я вам указал, чтобы увидеть, как прикрепить экспресс-приложение к функции.

Doug Stevenson 11.06.2019 18:56

Я посмотрел на это. он включал около дюжины файлов. какой конкретно файл вы имеете в виду? это index.js?

Mike Kim 11.06.2019 19:00

В документации не показано, как конкретно размещать программу, которую я написал в своем вопросе. он просто показывает, как размещать что-то совершенно другое с таким количеством других команд, как require('firebase-admin'), require('cookie-parser'), require('cors) и т. д. и т. д. код в документе в основном требует способа больше вещей и делать гораздо больше вещей, чем я пытаюсь сделать. Нет никакого смысла в том, что только для того, чтобы запустить мой простой код, мне нужно запустить дюжину других вещей и потребовать дюжину других вещей.

Mike Kim 11.06.2019 19:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
1 007
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Теперь перейдем к подходу, который действительно работает!

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

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

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

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

Спасибо за подробный ответ! теперь это работает правильно. и единственная проблема заключается в том, что встраивание CSS не работает, в то время как все остальное работает, но если я запускаю его через команду BASH, которая является узлом index.js после добавления app.listen(portNum), все работает отлично, включая встраивание CSS. Но я думаю, это отдельная тема.

Mike Kim 11.06.2019 20:25

Файл {functionUrl}/assets/todo-list.js загрузился в браузере? Вы можете проверить это на вкладке источников инструментов разработчика. Если файл js загружен, файл css тоже должен быть загружен, они оба обслуживаются промежуточным программным обеспечением express.static одинаково. Хотя вам следует подумать о загрузке статических ресурсов из другого места (возможно, CDN, даже Github работает для нескольких запросов). При таком подходе ваша облачная функция выполняется один раз для каждого из активов.

d_shiv 11.06.2019 20:37

Если он не загрузился, посмотрите на ошибку/ответ на вкладке «сеть» инструментов разработчика. По крайней мере, запрос должен быть запущен, возможно, поставщик облачных функций ограничивает количество параллельных запросов или что-то в этом роде.

d_shiv 11.06.2019 20:43

поэтому я только что проверил... и оказалось, что файл ./assets/todo-list.js тоже не загрузился. В консоли «проверить» он говорит: «Задание: 1 Отказался применять стиль из« локальный: 5000/активы/styles.css », потому что его тип MIME («текст / HTML») не является поддерживаемым типом MIME таблицы стилей, и включена строгая проверка MIME».

Mike Kim 11.06.2019 20:54

Хм, похоже промежуточное ПО express.static сработало не очень хорошо. Возможно какое-то ограничение на сервере. Сообщение об ошибке, которое вы опубликовали, объясняет, что вы получили ответ в формате html. Можно перейти на вкладку «Сеть» и обновить страницу. Найдите звонок для assets/styles.css и assets/todo-list.js в списке звонков. Нажмите на строку и посмотрите фактический ответ на вкладке preview / response, которая открывается справа. Ответ может иметь некоторое представление о том, что пошло не так. А пока вы можете включить эти файлы из Github или скопировать и вставить их прямо в свой файл ejs, чтобы все заработало!

d_shiv 11.06.2019 21:00

хм, я сделал то, что вы сказали, и для styles.css в предварительном просмотре было написано «НЕ ЗАГРУЗИТЬ ДАННЫЕ ОТВЕТА». А для todo-list.js в ответе говорилось: «Для этого запроса нет доступных данных ответа».

Mike Kim 11.06.2019 21:52

Другие вопросы по теме