Итак... из этого туториала на 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'). до сих пор не работает. Я читал документацию, но она была очень длинной, и мне хотелось, чтобы я полностью переделал все это, и я помню, как размещал файл JavaScript в Cloud Functions в прошлом, просто добавив пару строк кода, таких как: const functions = require(' firebase-функции'); и exports.app = functions.https.onRequest((запрос, ответ) => { response.send("Привет из Firebase!"); }); и я не знаю, почему это работало нормально в прошлом (например, в прошлом месяце), но не сейчас.
Одна вещь, которую я заметил, это то, что в коде, который я написал в своем вопросе, облачные функции работают нормально и показывают результат «Привет из Firebase!» и я не получил никакого сообщения об ошибке. просто программа «todo» не отображалась на веб-странице (вероятно, потому, что что-то не было встроено, пока часть Firebase работала правильно).
Внимательно посмотрите на пример, на который я вам указал, чтобы увидеть, как прикрепить экспресс-приложение к функции.
Я посмотрел на это. он включал около дюжины файлов. какой конкретно файл вы имеете в виду? это index.js?
В документации не показано, как конкретно размещать программу, которую я написал в своем вопросе. он просто показывает, как размещать что-то совершенно другое с таким количеством других команд, как require('firebase-admin'), require('cookie-parser'), require('cors) и т. д. и т. д. код в документе в основном требует способа больше вещей и делать гораздо больше вещей, чем я пытаюсь сделать. Нет никакого смысла в том, что только для того, чтобы запустить мой простой код, мне нужно запустить дюжину других вещей и потребовать дюжину других вещей.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваша первоначальная настройка не работает, потому что экспресс-приложение (созданное с помощью вызова 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. Но я думаю, это отдельная тема.
Файл {functionUrl}/assets/todo-list.js загрузился в браузере? Вы можете проверить это на вкладке источников инструментов разработчика. Если файл js загружен, файл css тоже должен быть загружен, они оба обслуживаются промежуточным программным обеспечением express.static одинаково. Хотя вам следует подумать о загрузке статических ресурсов из другого места (возможно, CDN, даже Github работает для нескольких запросов). При таком подходе ваша облачная функция выполняется один раз для каждого из активов.
Если он не загрузился, посмотрите на ошибку/ответ на вкладке «сеть» инструментов разработчика. По крайней мере, запрос должен быть запущен, возможно, поставщик облачных функций ограничивает количество параллельных запросов или что-то в этом роде.
поэтому я только что проверил... и оказалось, что файл ./assets/todo-list.js тоже не загрузился. В консоли «проверить» он говорит: «Задание: 1 Отказался применять стиль из« локальный: 5000/активы/styles.css », потому что его тип MIME («текст / HTML») не является поддерживаемым типом MIME таблицы стилей, и включена строгая проверка MIME».
Хм, похоже промежуточное ПО express.static сработало не очень хорошо. Возможно какое-то ограничение на сервере. Сообщение об ошибке, которое вы опубликовали, объясняет, что вы получили ответ в формате html. Можно перейти на вкладку «Сеть» и обновить страницу. Найдите звонок для assets/styles.css и assets/todo-list.js в списке звонков. Нажмите на строку и посмотрите фактический ответ на вкладке preview / response, которая открывается справа. Ответ может иметь некоторое представление о том, что пошло не так. А пока вы можете включить эти файлы из Github или скопировать и вставить их прямо в свой файл ejs, чтобы все заработало!
хм, я сделал то, что вы сказали, и для styles.css в предварительном просмотре было написано «НЕ ЗАГРУЗИТЬ ДАННЫЕ ОТВЕТА». А для todo-list.js в ответе говорилось: «Для этого запроса нет доступных данных ответа».
Эта строка кода не будет работать:
app.listen(5000, '127.0.0.1'). Вы не можете прослушивать некоторые порты в Cloud Functions. Если вы хотите запустить экспресс-приложение в Cloud Functions, используйте это в качестве примера: github.com/firebase/functions-samples/tree/master/….