so ..来自这个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(“ Hello from Firebase!”),我在实际网页上获得的唯一结果是“ Hello from Firebase!”。有什么方法可以使整个“待办事项列表”程序在我的实际网页上正常工作?
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的Hello!”);并只使用exports.app = functions.https.onRequest(app);,它就可以工作了……这意味着response.send(“ Firebase的你好!);使此代码无法正常工作。为什么?
答案 0 :(得分:2)
您的原始设置不起作用,因为从未启动Express应用程序(使用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对象,并通过中间件链进行传播。
现在,当您将Express应用程序app
传递给functions.https.onRequest
时,firebase系统将基本上把您的app
视为一个使用http.IncomingMessage
的函数。对象和一个http.serverResponse
对象作为参数。这是expressJS的一个未记录的功能,它调用该应用程序(存储在此处的app
中)作为分别提供IncomingMessage
和ServerResponse
实例作为第一和第二参数的函数,其行为类似于http请求是由基础服务器接收。请求和响应通过初始处理以及中间件链运行,就像快递服务器直接收到的任何请求一样。这可以用于少数情况下,即用户需要多个框架的混合,或者不能显式启动服务器,但是可以通过其他方式访问请求和响应对象。就像在这种情况下。
实际上,每次调用云函数时,firebase函数框架都将调用存储在app
引用中的快速应用程序作为函数,其余部分由中间件完成。