【问题标题】:Node.js, ajax - Frontend routingNode.js, ajax - 前端路由
【发布时间】:2019-02-13 06:26:02
【问题描述】:

我正在开发一个带有 node.js、jQuery、mongoose 和 MongoDB 的购物网站的 SPA 网站。 从 index.html 文件开始时,ajax 请求和响应可以完美运行。例如,从http://localhost:3000 开始,有人点击了一个名为“产品”的链接,我向服务器发送了一个 ajax 请求,服务器异步发送回必要的产品信息,从而导致http://localhost:3000/products。但问题是,如果有人直接在搜索栏中输入http://localhost:3000/products,它会显示产品的 json 表示。

这是我的代码:

script.js

function redirect (link) {
    $.ajax({
        type: 'GET',
        url: 'http://localhost:3000/' + link,
        contentType: 'application/json',
        data: {
            link
        },
        success: function (res) {
            let container = $('#contentToSwap');
            container.html('');
            res.products.forEach(function (products_) {
              ...
            });
        }
    });
}

app.js

var Product = require('./models/product');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var path = require('path');
var express = require('express');

var app = express();

mongoose.connect('mongodb://localhost:27017/shopping');

var PORT = process.env.PORT || 3000;

app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());

app.get('*', function(req, res) {
    Product.find(function(err, docs) {
        let productChunks = [];
        let chunksize = 4;
        let display = [];
        for (var i = 0; i < docs.length; i++) {
            if (docs[i].productType == req.query.link) display.push(docs[i]);
        }
        for (var i = 0; i < display.length; i += chunksize) {
            productChunks.push(display.slice(i, i + chunksize));
        }
        res.send({ products: productChunks });
    });
});

app.listen(PORT, function () {
    console.log('Listening on port ' + PORT);
});

所以如果用户没有从 index.html 文件开始,我需要某种前端路由。我知道我可以编写自己的路由器来正确路由 url,并且我可以将所有请求路由回 index.html,如

app.get('*', function(req, res) {
    res.sendFile(__dirname + '/public/index.html');
});

但是当有人单击链接时,我无法从服务器加载所有必要的产品信息。所以我对如何解决这个问题有点困惑。任何帮助表示赞赏

【问题讨论】:

  • 尝试将type: 'GET'改为type: 'POST'

标签: javascript jquery node.js


【解决方案1】:

这通常是通过为所有返回 json 数据的路由添加特定的 url 前缀(例如 /api)将 api 路由与普通路由分开来实现的。您可以做的是指定/api/whatever-you-want,使其成为您的ajax 调用的目标并将其置于app.get('*' ... 之上。

由于路由和中间件函数是从上到下解析的,它只会由您的 ajax 调用匹配,而 /products 不受影响。

回答问题——如果请求不是由 ajax 生成的,是否可以将用户从 /api/products 重定向到 /product?

是的,可以通过将请求查询参数添加到 ajax 调用中,该参数在正常调用中不会出现,然后在服务器端检查这些参数并决定如果它(该特定查询参数)是否丢失该怎么办。

让我们假设一些客户端 JS 生成 ajax 调用。

fetch('/api/products?api=true')
  .then((data) => data.json())
  .then((json) => console.log(json));

注意请求 url - /api/products?api=true

现在假设来自 html 文件的正常调用。

<a href="/products">products</a>

这两个调用的不同之处在于api 查询参数(ajax 调用有,另一个没有)。

对于任务的服务器端部分——请求查询参数对象可以通过请求对象 (req.query) 上的 query 属性访问。

app.get('/api/products', (req, res) => {
    if (!req.query.api) {
        // if get request doesn't contain api param. then
        // handle it accordingly, e.g. do redirect
        return res.redirect('/products');
    }

    // request comming from ajax call, send JSON data back
    res.json({ randomStuff: 'abcd' });
});

【讨论】:

  • 是的,成功了,就像这样完美地工作。是否可以重定向可能意外尝试访问“../api/whatever”网址的用户?例如,当他们尝试访问 app/api/products 以将他们重定向到 app/products 时?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 2017-12-20
  • 1970-01-01
  • 2010-12-14
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多