Router.express() -> 表达 router.use 的正确方法是什么?



对于router.use,它不再像这样工作:

router.use("/api", apiRoutes);

相反,会引发一个错误:throw new typeerror('router.use((需要一个中间件函数,但得到了'+gettype(fn((

我该如何重新设定该表达式的用途,使其发挥作用?到目前为止,我还没有发现任何有用的例子。以下是我的一些示例代码:

routes/index.js(这不起作用(

const path = require("path");
const router = require("express").Router();
const apiRoutes = require("./api");
// API Routes
router.use("/api", apiRoutes);**// this throws an error**
router.use(function(req, res) {
res.sendFile(path.join(__dirname, "../client/build/index.html"));
});
module.exports = router;

以下是我试图重新定位的一个例子,但我认为这是不对的:

var path = require("path");
var router = require("express").Router();
var apiRoutes = require("./api");
//API Routes
//authRouter.use(require('./authenticate').basic(usersdb))
//router.use("./api", apiRoutes);
console.log("Hitting API routes...")
router.use("./api", function(req, res, next) { **//re-purpsose attempt here**
res.send(apiRoutes)
console.log("API Routes:", apiRoutes)
next()
});
console.log("API Routes hit")
// //If no API routes are hit, send the React app
//    router.use(function(req, res) {
//    res.sendFile(path.join(__dirname, "../client/public/index.html"));
//    });
module.exports = router

这是我得到的总体错误(返回404(:获取/api/website_1_function_call/screep 404 4.004毫秒-173

我知道这可能是间接的原因,但我真的不确定router.use部分。

我确信这些路线没有被正确击中,我想修复。

如有任何建议,我们将不胜感激。提前谢谢。

以下是更多代码:

server.js

require("dotenv").config();
var express = require("express");
var cors = require('cors');
var bodyParser = require('body-parser');
var logger = require("morgan");
//const mongoose = require("mongoose");
var db = require("./models")
var routes = require("./routes");
var app = express();
var PORT = process.env.PORT || 3001;
var path = require('path');
//Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(bodyParser.json());
//Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === 'production') {
app.use(express.static("client/build"));
}
app.use(cors());
app.use(logger("dev"));
//Add routes, both API and view
app.use(routes);
//replaced with below:
//app.use(app.router);
//routes.initialize(app);
// //Connect to the Mongo DB 
// mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/kaibru");
var syncOptions = { force: false };
// If running a test, set syncOptions.force to true
// clearing the `testdb`
if (process.env.NODE_ENV === "test") {
syncOptions.force = true;
};
// Starting the server, syncing our models ------------------------------------/
db.sequelize.sync(syncOptions).then(function() {
app.listen(PORT, function() {
console.log(
"==> 🌎  Listening on port %s. Visit http://localhost:%s/ in your browser.",
PORT,
PORT
);
});
});
// //Start the API server
// app.listen(PORT, function() {
//     console.log(`🌎 ==> API Server now listening on PORT ${PORT}!`);
// });

routes/index.js

var path = require("path");
var router = require("express").Router();
var apiRoutes = require("./api");
//API Routes
//authRouter.use(require('./authenticate').basic(usersdb))
//router.use("/api", apiRoutes);
console.log("Hitting API routes...")
router.use("/api", function(req, res, next) { // this is my re-purpose 
attempt
apiRoutes
console.log("API Routes:", apiRoutes)
//    next()
}); // this is my r-purpose attempt
console.log("API Routes hit")
// //If no API routes are hit, send the React app
//    router.use(function(req, res) {
//    res.sendFile(path.join(__dirname, "../client/public/index.html"));
//    });
module.exports = router

routes/api/index.js

var router = require("express").Router();
require("./website_1");
var website_1Routes = require("./website_1_function_call");
//const userRoutes = require("./user");
//Website_1 routes
//http://localhost:3000/api/website_1_function_call/scrape
//authRouter.use(require('./authenticate').basic(usersdb))
//router.use("/website_1_function_call", website_1Routes);
//experimental use
router.use("/website_1_function_call", function(req, res, next) { // this is my re-purpose attempt
website_1Routes
console.log("website_1Routes:", website_1Routes)
//     next()
}); //this is my re-purpose attempt
//router.use("/user", userRoutes); 
module.exports = router

路由/api/website_1_function_call.js

require("./website_1");
require("./website_1_db");
require("./website_1_router");
//Call scrape functions from website_1 file
mainscrape();
//specificScrape() //let's leave this one dormant for now
//Now for saving to database
saveToDatabase();
//Now for the routes
routing();

我认为我的重新定位尝试成功了(我删除了next((,因为之后没有定义的路由(。它似乎正在处理中。然而,现在我的响应挂起了,发生了这种情况:

GET /api/website_1_function_call/scrape - - ms - -

这在浏览器控制台中打印:

GET http://localhost:3000/api/website_1_function_call/scrape 
net::ERR_EMPTY_RESPONSE
0.chunk.js:871 Uncaught (in promise) Error: Network Error
at createError (0.chunk.js:871)
at XMLHttpRequest.handleError (0.chunk.js:366)

所以现在我认为我的scraper代码和更新数据库的代码不起作用。

刮擦功能代码:

//var express = require("express");
var router = require("express").Router();
require("../../controllers/website_1controller");
//requiring this website's models
var Items_1 = require("../../models/website_1");
//require("./website_1_db");
//require("./website_1_router");
// Our scraping tools
// Axios is a promised-based http library, similar to jQuery's Ajax method
// It works on the client and on the server
var axios = require("axios");
var cheerio = require("cheerio");
mainscrape = function()  {
//Now to configure the routes
router.get("/scrape", function(req, res) {
//instead of simple res.render, user router.get  
console.log("scraping started...");
//Grab the html body with axios    
axios.get("url placeholder").then(function(response) {
//Load to cheerio and save to $ selector
console.log("Scraping all greenheartshop mainpage...");
var $ = cheerio.load(response.data);
var output = [];
var promises = [];
//Now we need to grab the title reference for each article
$("article").each(function(i, element) {
//save empty result object
var result = {};
//thumbnail
result.thumbnail = $(this)
//.children("article.product-grid-item.product-block").html()
.children("figure.product-item-thumbnail")
.children("a")
.attr("href")
//console.log("result thumbnail")
//console.log(result)
console.log(result.thumbnail)
var result = {}
//details
result.detail= $(this)
//.children("product-item-mask").html()
.children("div.product-item-details")
// .children("div.product-item-brand")
// .children("h5.product-item-title")
// .children("a")
// .children("div.product-item-price")
//.children("product-price-line")
//.children("price-value")
.text()
//result.detail = result.detail.trim();
//console.log("result detail")
//console.log(result)
console.log(result.detail)
//Capture the scraped data and save to database
console.log("Capturing Scrape")
if(result.detail !== '') {
var promise = Items_1
.saveToDatabase(result, result, {upsert:true, new:true})
console.log("saveToDatabase");
promises.push(promise);
}
Promise.all(promises).then((data) => {
res.json(data);
});
//saveToDatabase();
// if (result.thumbnail !== {} && result.detail !== "") {
//     var promise = Items_1
//     // .items_1_create({
//     //     resultThumbnail: result.thumbnail,
//     //     resultDetails: result.detail  
//     //   })
//     promises.push(promise)
//     // .then(dbModel => output.push(dbModel));
//     Promise.all(promises).then((data) => {
//       res.json(data)
//     })
//   }

});
});
//Now to CREATE the results using controller file
// console.log("creating items in the database now...")
// router.post('/scrape', website_1Controller.items_1_create);
//Now to display the results
// console.log("Items now being displayed...")
// router.get('/scrape/display', website_1Controller.items_1_list)
});
}
module.exports = router;
module.exports = mainscrape;
module.exports = specificScrape;

更新数据库的代码:

require("../../controllers/website_1controller");
require("./website_1");
var Items_1 = require( "../../models");
//After scraping the main page, the following function is to save to the 
database
saveToDatabase = function() {
//prepare the data
var result = {}
var dataToStore = Items_1.items_1_create
console.log(dataToStore)
//console.log(items_1_create)
//insert data to the database
// dataToStore.save().// We will not sue this part for now
//     then(() => {
//         console.log("Data successfully saved");
//     }).catch(err => {
//         console.log("Error: ", err);
//     });
}
module.exports = saveToDatabase;

最终路线代码(刮取完成后(

var website_1Controller = require("../../controllers/website_1controller");
var router = require("express").Router();
routing = function() {
//Now to CREATE the results using controller file
console.log("creating items in the database now...")
//router.route("/browse")
router.post('/browse', website_1Controller.items_1_create);
router.get('/browse', website_1Controller.items_1_list);
//Now to display the results
console.log("Items now being displayed...")
//router.route("/browse:search")
router.get('/:search', website_1Controller.items_1_specific);
};
require("./website_1");
module.exports = routing;
module.exports = router;

型号

'use strict';
// Dependencies
// =============================================================
// Sequelize (capital) references the standard library
//var Sequelize = require("sequelize");
// sequelize (lowercase) references our connection to the DB.
//var sequelize = require("../config/connection.js");
// Creates a "Items_1" model that matches up with DB
module.exports = function(sequelize, DataTypes) {
var Items_1 = sequelize.define("Items_1", {
// the routeName gets saved as a string
detail: DataTypes.STRING,
// the name of the character (a string)
thumbnail: DataTypes.BLOB,
// the character's role (a string)
//role: Sequelize.STRING,
// the character's age (a string)
//age: Sequelize.INTEGER,
// and the character's force points (an int)
//forcePoints: Sequelize.INTEGER
}, {
// disable the modification of tablenames; By default, sequelize will 
automatically
// transform all passed model names (first parameter of define) into 
plural.
// if you don't want that, set the following
freezeTableName: true
});
return Items_1;
//Syncs with DB
//Items_1.sync();
// Makes the Items_1 Model available for other files (will also create a table)
};

控制器

// *********************************************************************************
// website_1controllers.js - this file offers a set of routes for displaying and saving data to the db
// *********************************************************************************
// Dependencies
// =============================================================
var db = require("../models");
//display results for mainpage scrape
exports.items_1_create = function(req, res) {
db.Items_1.findOneAndUpdate(req.body, req.body, {upsert: true, new: 
true})
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err))
console.log("findOneAndUpdate complete")
},
exports.items_1_list = function(req,res) {
db.Items_1.findAll({})
},
exports.items_1_specific = function(req,res) {
db.Items_1.findById(req.params.search)
},
function(err, results) {
if (err) { return next(err); } //Error in API usage.
if (results.result.thumbnail==={} && results.result.detail==="") {//No 
Results.
var err = new Error('Results not found');
err.status = 404;
return next(err)
}
//Successful, so render
res.render("click_results", { title: 'Click Results', resultThumbnail: 
result.thumbnail, resultDetails: result.detail });
}

因此,新的问题是回应悬而未决。我认为这是因为更新数据库的代码不起作用(使用sequelize(。如果还需要什么,请告诉我,并提前感谢您。

感谢大家的投入。在回顾之后,我发现函数本身不必像我最初认为的那样被重新使用。。。我不知道,例如,如果您正在使用"router.use"("/directoy",directory(,并且您正在连续使用它来指向不同的目录,那么最终的目录命中必须有一个定义好的路由,如router.get((。我将代码模块化,最终的目录只是一个函数列表(其中一个函数具有router.get方法(。这不起作用。当我将文件直接指向包含router.get方法的代码时,我抓取的数据会返回到终端。我只是想分享我的发现,至少因为我根本不知道这一点。非常感谢@mehta rohan和@Anand Undavia的真知灼见。我仍在尝试将数据呈现到页面上,但这完全是一个不同的问题。

最新更新