为 HTML 页面调用 ExpressJS 作为 Rest API
Call ExpressJS as Rest API for HTML page
我正在创建带有按钮的网页,以使用 Rest API 通过 ExpressJS、NodeJs 构建从服务器加载数据。
var express=require('express');
var mysql=require('mysql');
var app=express();
var server=app.listen(3000,function(){
console.log("Express is running on port 3000");
});
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
HTML 此应用程序的页面如下所示
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function() {
$('div').append("done !!! - ");
});
});
});
</script>
当我在浏览器中 运行 http://localhost:3000/search 时,它会从数据库中输出 "name" 。但是我怎样才能看到 index.html 页面并使其在单击按钮时加载。
这是我想使用一个简单的 index.html 页面来测试一些前端代码时使用的代码。
app.get("/", function(req, res) {
res.sendFile( __dirname + '/index.html')
});
这会将根路径映射到您的 index.html。 __dirname 假定 index.html 文件与 express 的初始 server/app 文件位于同一目录中。如果你想让它更通用,你可以做类似下面的事情,但是你需要手动将 index.html 添加到浏览器的地址栏,但它也可以让你加载你想要的任何其他静态文件。
app.get(/^(.+)$/, function(req, res){
res.sendFile( __dirname + req.params[0]);
});
您遇到的问题是您正在使用 Express 作为渲染框架。如果您想使用 REST/API 构建应用程序,框架不应呈现视图或模板。网页导航应该是单独的(例如 Angular JS)。在您的情况下,当您调用 /search 时,您实际上只是在服务器中调用某些内容而没有任何呈现指令。这就是为什么您看到响应 JSON 对象而不是 html 模板的原因。
那么,该怎么办?..您需要在客户端制作一个导航应用程序,只需在模板中导航,没有任何异常,然后对您的按钮进行编程以向某些 api 发出请求url(类似于:localhost:3000/api/search)并根据响应的内容做一些事情:比如填充 table,以某种方式显示它们......
我推荐你试试Angular JS。我相信它可以帮助你
干杯
更新:
OP 提问:
"my question is not what code say....my question is how to change the
code so that expressjs works as RESTful API and not rendering engine"
为了在此处将 express 用作 RESTful API,您首先需要提供一个静态页面。
换句话说,步骤如下:
1. 让您的快速服务器提供一个 静态页面 。
2. 然后获取该页面上的按钮,向位于 /search
的 api 端点发出 GET
请求(单击时)。
1 在我的回答第二部分有解释。
2 应该已经工作了,您只需要提供页面并单击按钮!
我在我的回答的第一部分解释了为什么这不起作用。您不能简单地导航到 /search
。我想这就是你所说的 "not use it as a render engine".
原答案:
要了解此处发生的情况,最好查看您如何在服务器端代码中处理请求:
When I run http://localhost:3000/search in browser it gives me output with "name" from the database.
那个代码是:
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
这意味着无论何时 GET 请求到达您的路由(在本例中,localhost:3000
上的路径 /search
),回调函数都会执行。本质上,当您访问 localhost:3000/search
时,您的浏览器会发送一个 GET
请求,Express 检查*请求是否与每个路由匹配,最后转到 "ok, that's the GET request I need to respond to, let's start searching!"。
所以它的行为符合预期。当然,这不是你想要的...
But how can I see the index.html page and make it load on button click
尝试这样的事情:
app.get('/', function(req,res) {
res.sendfile('public/index.html');
});
它可能无法按原样工作,具体取决于您的 html 的定义位置和您为其命名的内容。 记得发送正确的文件。
一个更简单的推理方法是让 express 知道您正在提供静态 html。**
这可以用
来完成
app.use("/", express.static(__dirname));
但再次确保上面定义的 html 位于正确的根文件夹(可能命名为 server
或类似名称)的文件中,名称为 index.html
(并且只有其中之一)。
(请参阅底部有关 express 中间件如何工作和静态服务 HTML 的链接)
最后,您先实现这个答案的后半部分,这样您就可以直接转到 localhost:3000
加载您的索引页。该页面将有一个按钮。 然后,您将能够单击该按钮并向您的 /search
路由发出请求,而无需重定向。 name
的内容现在应该返回到浏览器(而不是作为新页面提供)。
*更多关于请求如何获得 checked/processed here.
**有关服务的更多信息 static html. This blog on express fundamentals 也可能有用。
1-您必须为 index.html
添加路由
app.get("/index", function(req, res) {
res.render(index.html);
});
然后在您的 ajax 代码中,您可以使用 window.location[=12 重定向到 /index =]
2-可以直接渲染index.html。
像这样
app.get("/search", function(req, res) {
res.render(search.html,{});
});
app.get('/index',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.render(index.html,{data:data});
});
});
然后在单击按钮时重定向到 /index 上的页面。
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function(data) {
$('div').append(data);
});
});
});
</script>
您可以从 jquery api 文档中阅读有关 $.ajax() 的文档
http://api.jquery.com/jQuery.ajax/
我正在创建带有按钮的网页,以使用 Rest API 通过 ExpressJS、NodeJs 构建从服务器加载数据。
var express=require('express');
var mysql=require('mysql');
var app=express();
var server=app.listen(3000,function(){
console.log("Express is running on port 3000");
});
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
HTML 此应用程序的页面如下所示
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function() {
$('div').append("done !!! - ");
});
});
});
</script>
当我在浏览器中 运行 http://localhost:3000/search 时,它会从数据库中输出 "name" 。但是我怎样才能看到 index.html 页面并使其在单击按钮时加载。
这是我想使用一个简单的 index.html 页面来测试一些前端代码时使用的代码。
app.get("/", function(req, res) {
res.sendFile( __dirname + '/index.html')
});
这会将根路径映射到您的 index.html。 __dirname 假定 index.html 文件与 express 的初始 server/app 文件位于同一目录中。如果你想让它更通用,你可以做类似下面的事情,但是你需要手动将 index.html 添加到浏览器的地址栏,但它也可以让你加载你想要的任何其他静态文件。
app.get(/^(.+)$/, function(req, res){
res.sendFile( __dirname + req.params[0]);
});
您遇到的问题是您正在使用 Express 作为渲染框架。如果您想使用 REST/API 构建应用程序,框架不应呈现视图或模板。网页导航应该是单独的(例如 Angular JS)。在您的情况下,当您调用 /search 时,您实际上只是在服务器中调用某些内容而没有任何呈现指令。这就是为什么您看到响应 JSON 对象而不是 html 模板的原因。
那么,该怎么办?..您需要在客户端制作一个导航应用程序,只需在模板中导航,没有任何异常,然后对您的按钮进行编程以向某些 api 发出请求url(类似于:localhost:3000/api/search)并根据响应的内容做一些事情:比如填充 table,以某种方式显示它们......
我推荐你试试Angular JS。我相信它可以帮助你
干杯
更新:
OP 提问:
"my question is not what code say....my question is how to change the code so that expressjs works as RESTful API and not rendering engine"
为了在此处将 express 用作 RESTful API,您首先需要提供一个静态页面。
换句话说,步骤如下:
1. 让您的快速服务器提供一个 静态页面 。
2. 然后获取该页面上的按钮,向位于 /search
的 api 端点发出 GET
请求(单击时)。
1 在我的回答第二部分有解释。
2 应该已经工作了,您只需要提供页面并单击按钮!
我在我的回答的第一部分解释了为什么这不起作用。您不能简单地导航到 /search
。我想这就是你所说的 "not use it as a render engine".
原答案:
要了解此处发生的情况,最好查看您如何在服务器端代码中处理请求:
When I run http://localhost:3000/search in browser it gives me output with "name" from the database.
那个代码是:
app.get('/search',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.end(JSON.stringify(data));
});
});
这意味着无论何时 GET 请求到达您的路由(在本例中,localhost:3000
上的路径 /search
),回调函数都会执行。本质上,当您访问 localhost:3000/search
时,您的浏览器会发送一个 GET
请求,Express 检查*请求是否与每个路由匹配,最后转到 "ok, that's the GET request I need to respond to, let's start searching!"。
所以它的行为符合预期。当然,这不是你想要的...
But how can I see the index.html page and make it load on button click
尝试这样的事情:
app.get('/', function(req,res) {
res.sendfile('public/index.html');
});
它可能无法按原样工作,具体取决于您的 html 的定义位置和您为其命名的内容。 记得发送正确的文件。
一个更简单的推理方法是让 express 知道您正在提供静态 html。**
这可以用
来完成
app.use("/", express.static(__dirname));
但再次确保上面定义的 html 位于正确的根文件夹(可能命名为 server
或类似名称)的文件中,名称为 index.html
(并且只有其中之一)。
(请参阅底部有关 express 中间件如何工作和静态服务 HTML 的链接)
最后,您先实现这个答案的后半部分,这样您就可以直接转到 localhost:3000
加载您的索引页。该页面将有一个按钮。 然后,您将能够单击该按钮并向您的 /search
路由发出请求,而无需重定向。 name
的内容现在应该返回到浏览器(而不是作为新页面提供)。
*更多关于请求如何获得 checked/processed here.
**有关服务的更多信息 static html. This blog on express fundamentals 也可能有用。
1-您必须为 index.html
添加路由app.get("/index", function(req, res) {
res.render(index.html);
});
然后在您的 ajax 代码中,您可以使用 window.location[=12 重定向到 /index =]
2-可以直接渲染index.html。 像这样
app.get("/search", function(req, res) {
res.render(search.html,{});
});
app.get('/index',function(req,res){
var mysql=require('mysql');
var connection = mysql.createConnection({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'node-test'
});
connection.connect();
connection.query('SELECT name from users', function(err, rows, fields) {
if (err) throw err;
var data=[];
for(i=0;i<rows.length;i++){
data.push(rows[i].name);
}
res.render(index.html,{data:data});
});
});
然后在单击按钮时重定向到 /index 上的页面。
<button >Load from server</button>
<div></div>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','button', function(){
$.ajax({
url: "http://localhost:3000/search"
}).done(function(data) {
$('div').append(data);
});
});
});
</script>
您可以从 jquery api 文档中阅读有关 $.ajax() 的文档 http://api.jquery.com/jQuery.ajax/