为 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/