中间件多次被执行?

时间:2016-11-07 23:53:08

标签: javascript node.js express

我正在尝试使用express创建一个url shortener app。路由/shorten/:url*/:code分别有2个中间件。不知怎的,当我发出像/shorten/iamarshad.com这样的请求时(请求没有格式化并且我的validateUrl方法会失败),处理该请求的中间件有时会被执行两次,有时会执行三次。为什么会这样? route.js的代码:

var express = require("express");
var router = express.Router();
var crypto = require("./crypto");

var styles = "<style>@import url('https://fonts.googleapis.com/css?family=Cormorant+Garamond');" +
            "body{background: #fefefe; word-wrap: break-word;}" +
            "p {font-size: 30px;color: #b33c66;font-family: 'Cormorant Garamond', monospace;text-align: center;" +
            "margin-top: 40vh;font-weight: 500;word-spacing: 2px;}</style>";

function verifyUrl(req, res, next) {
    console.log("/shorten middleware called");
    req.params.url +=  req.params[0];
    console.log(req.params.url);
    if (validateUrl(req.params.url)) {
        req.db.collection("counter")
        .find({_id: "counter"})
        .toArray(function (err, docs) {
            if (err) console.error("Error occurred while getting COUNTER document:", err);

            req.encodedId = crypto.encode(docs[0].count);

            next();
        });
    }
    else {
        var elem = "<p>Please enter correct and formatted url!</p>";
        res.send(styles + elem);
    }
}


function incrementCounter(req, res, next) {
    // increasing counter
    req.db.collection("counter")
        .update(
            { 
                _id: "counter"
            },
            {
                $inc : {
                    count : 1
                }
            }
        );

    next();
}

function insertUrlDocument(req, res, next) {
    //inserting new url document
    var obj = {original_url: req.params.url, _id: req.encodedId, entry_time: new Date().toUTCString()};
    req.db.collection("urls")
        .insert(obj, function(err, data) {
            if(err) console.error("Error happened while adding new document:", err);
        });
    next();
}

function sendResponse(req, res) {
    var elem = "<p>" + JSON.stringify({'original_url': req.params.url, 'short_url': 'https://shorten-that.herokuapp.com/' + req.encodedId}) + "</p>";
    res.send(styles + elem);
}

function validateUrl(url) {
  var format = /(http:\/\/|https:\/\/)[a-z0-9\-]+[.]\w+/;
  return (format.test(url));
}

router.get("/:code", function(req, res) {
    console.log("/:code middleware called with url", req.params.code);
    var code = req.params.code.toString();
    // searching short-url-id
    req.db.collection("urls")
        .find({_id: code})
        .toArray(function(err, docs) {
            if(err) console.error("Error occurred while searching urls:", err);
            console.log(docs);
            if(docs.length > 0)
                res.redirect(docs[0]["original_url"]);
            else {
                var elem = "<p>Oops, wrong url requested!</p>";
                res.send(styles + elem);
            }
        });
});

// better solution needed 
router.get("/shorten/:url*", [verifyUrl, incrementCounter, insertUrlDocument, sendResponse]);

module.exports = router;

server.js的代码:

var express = require("express")
    , mongo = require("mongodb").MongoClient
    , port = process.env.PORT || 8080
    , path = require("path")
    , routes = require("./routes")
    , favicon = require("serve-favicon");  

var app = express();
app.use(favicon(path.join(__dirname, 'public','favicon.png')));
app.use(express.static(path.join(__dirname, "public")));

var url = 'mongodb://localhost:27017/url-shortener';

mongo.connect(url, function(err, db) {
    if (err) console.error("Error occurred while connecting to db:", err);

    console.log("successfully connected to db.");

    app.use(function(req, res, next) {
        req.db = db;
        next();
    });        

    app.use("/", routes);
});

app.listen(port, function() {
   console.log("App running on", port); 
});

0 个答案:

没有答案