This is my node js server code. For some reason my images don’t load. Any help please?
At one time it worked, but all requests gave the same images, no matter what image I had in the folder
const express = require("express");
const fs = require("fs");
const { v4: uuidv4 } = require("uuid");
const multer = require("multer");
const path = require("path");
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.use(express.static("public"));
// Create chatbot
app.get("/create", (req, res) => {
const chatbotId = uuidv4();
const chatbotFolderPath = `public/chatbots/${chatbotId}`;
// Create a folder for the new chatbot
fs.mkdirSync(chatbotFolderPath, { recursive: true });
// Copy the template to the new chatbot folder
fs.copyFileSync(
"public/templates/chatbot_template.html",
`${chatbotFolderPath}/index.html`
);
// Copy the images folder
fs.mkdirSync(`${chatbotFolderPath}/images`);
fs.readdirSync("public/templates/images").forEach((file) => {
fs.copyFileSync(
`public/templates/images/${file}`,
`${chatbotFolderPath}/images/${file}`
);
});
// Copy the colors.json file
fs.copyFileSync(
"public/templates/colors.json",
`${chatbotFolderPath}/colors.json`
);
// Copy the bot_info.json file
fs.copyFileSync(
"public/templates/bot_info.json",
`${chatbotFolderPath}/bot_info.json`
);
res.send(`Your unique chatbot ID is: ${chatbotId}`);
});
// Serve static files for all chatbots
/* app.use("/images/:chatbotId", (req, res, next) => {
const { chatbotId } = req.params;
const chatbotImagesPath = `public/chatbots/${chatbotId}/images`;
express.static(chatbotImagesPath)(req, res, next);
}); */
/* app.use(
"/images/:chatbotId",
express.static(path.join(__dirname, "public/chatbots"))
); */
// View chatbot
app.get("/:chatbotId", (req, res) => {
const { chatbotId } = req.params;
const chatbotFilePath = `public/chatbots/${chatbotId}/index.html`;
// This makes sure the user can get the images
// Bug: This app.use is updated every time a chatbot is created, so only the
// most recently created chatbot's images will be available for use
app.use(
"/images",
express.static(__dirname + `/public/chatbots/${chatbotId}/images`)
);
// http://localhost:3000/images/a3cfb70c-16ee-4557-be19-cf15ed1b3348/logo.jpg
/* app.use("/images/:chatbotId", (req, res, next) => {
const { chatbotId } = req.params;
const chatbotImagesPath = `public/chatbots/${chatbotId}/images`;
express.static(chatbotImagesPath)(req, res, next);
}); */
fs.access(chatbotFilePath, fs.constants.F_OK, (err) => {
if (err) {
res.status(404).send("Chatbot not found");
} else {
res.sendFile(__dirname + `/public/chatbots/${chatbotId}/index.html`);
}
});
});
// Upload
const upload = multer({ dest: "public/uploads/" });
app.post("/upload", upload.single("logo"), (req, res) => {
// req.file contains information about the uploaded file
const uploadedLogo = req.file;
// Move the uploaded file to the appropriate location (e.g., chatbot folder)
const chatbotId = req.body.chatbotId; // Assuming you have a way to associate the logo with a chatbot
const chatbotFolderPath = `public/chatbots/${chatbotId}`;
const logoPath = `${chatbotFolderPath}/images/logo.jpg`; // Define the path for the logo
fs.rename(uploadedLogo.path, logoPath, (err) => {
if (err) throw err;
res.send("Logo uploaded successfully!");
});
});
// Color scheme
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
This is an example of I try to get the images inside
<div class="company">
<img src="./images/logo.jpg" alt="company-logo" />
<h3 id="company-name">Your Company</h3>
</div>
I have been debugging this for 2 hours but I can’t seem to wrap my head around it
2
Answers
This solution works perfectly.
You could handle multiple
chatbotId
values by supplying more than one middleware function argument toapp
HTTP request methods such asapp.get
. A third argument passed to all middleware functions is usually namednext
in code. Calling it invokes the next middleware function provided to theapp
method.In the example below,
app.get
first checks if the chatbox exists, and sends an error response if it doesn’t, or callsnext
if it does.The second handler in the route simply calls
express.static
to serve files from the correct chatbot folder. In express the default file served for a request with no filename isindex.html
(which can be changed in express configuration) so special handling for an index file may not be required.Example:
fsPromises.access
(notfs.access
) to asynchronously check if the chatbot folder exists.Update Note:
As I understand it,
express.server
resolves thereq.url
against the base folder path provided as its argument. Hence you probably need to adjustreq.url
to remove thechatbot:
component before using it, fairly easily accomplished in thethen
clause after thefsPromises
call by replacingwith