Just started learning node js in my school. They gave us this half-finished task and i need to make the next and prev buttons work. However i get some errors in the console the moment i run the index.html. The errors are:
"Fetch API cannot load file:///C:/Users/Jack/Desktop/Books_H/book-site/public/api/books. URL scheme must be "http" or "https" for CORS request."
and the other one is :
"Uncaught (in promise) TypeError: Failed to fetch at HTMLDocument.document.addEventListener".
I dont even know how to start to solve this problem. Any help?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1000, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
</head>
<body>
Hello from the other side! <b>Total: <span id="total"></span></b><br/>
<button id="author">Sort by author</button>
<button id="title">Sort by title</button>
<table id="books" border="1">
<tr>
<th>
Author
</th>
<th>
Book Title
</th>
</tr>
</table>
<script src="index.js"></script>
</body>
</html>
The java script file
document.addEventListener("DOMContentLoaded", () => {
processResponse(fetch("api/books"));
document.getElementById("author").addEventListener("click", () =>{
processResponse(fetch("api/books?sortby=author"))
});
document.getElementById("title").addEventListener("click", () =>{
processResponse(fetch("api/books?sortby=title"))
});
});
function processResponse(response) {
let table = document.getElementById("books");
let total = document.getElementById("total");
response.then(data => data.json())
.then(value => {
table.innerHTML = "";
const tr = document.createElement("tr");
let th = document.createElement("th");
th.innerHTML = "Author";
tr.appendChild(th);
th = document.createElement("th");
th.innerHTML = "Book Title";
tr.appendChild(th);
table.appendChild(tr);
for (let index = 0; index < value.books.length; index++) {
const book = value.books[index];
const tr = document.createElement("tr");
let td = document.createElement("td");
td.innerHTML = book.author;
tr.appendChild(td);
td = document.createElement("td");
td.innerHTML = book.title;
tr.appendChild(td);
table.appendChild(tr);
}
total.innerHTML = value.total;
});
}
server.js file
const fs = require('fs');
const express = require('express');
const app = express();
app.use(express.static("public"));
app.get("/", (req, res) => {
res.sendFile("index.html", { root: __dirname + "/public" });
});
const apiRouter = express.Router();
apiRouter.get("/books", (req, res) => {
let sortOrder = req.query["sortby"];
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
if (sortOrder === "author") {
books.sort((a, b)=> a.author.localeCompare(b.author));
} else if (sortOrder === "title") {
books.sort((a, b)=> a.title.localeCompare(b.title));
}
res.send(JSON.stringify({
books: books.slice(0, 50),
total: books.length
}));
});
})
apiRouter.get("/books/title", (req, res) => {
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
let titles = books.map(book => book.title);
res.send(JSON.stringify(titles));
});
})
apiRouter.get("/books/author", (req, res) => {
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
let authors = books.map(book => book.author);
res.send(JSON.stringify(authors));
});
})
app.use("/api", apiRouter);
app.listen(8080, () => console.log('Example app listening on port 8080!'));
/*
And the books.json file that i guess you dont need so i wont post it.
My folder structure is:
Books > data Folder > books.json.
Books > public Folder > index.html.
Books > public Folder > index.js.
Books > server.js.
*/
Just started learning node js in my school. They gave us this half-finished task and i need to make the next and prev buttons work. However i get some errors in the console the moment i run the index.html. The errors are:
"Fetch API cannot load file:///C:/Users/Jack/Desktop/Books_H/book-site/public/api/books. URL scheme must be "http" or "https" for CORS request."
and the other one is :
"Uncaught (in promise) TypeError: Failed to fetch at HTMLDocument.document.addEventListener".
I dont even know how to start to solve this problem. Any help?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1000, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
</head>
<body>
Hello from the other side! <b>Total: <span id="total"></span></b><br/>
<button id="author">Sort by author</button>
<button id="title">Sort by title</button>
<table id="books" border="1">
<tr>
<th>
Author
</th>
<th>
Book Title
</th>
</tr>
</table>
<script src="index.js"></script>
</body>
</html>
The java script file
document.addEventListener("DOMContentLoaded", () => {
processResponse(fetch("api/books"));
document.getElementById("author").addEventListener("click", () =>{
processResponse(fetch("api/books?sortby=author"))
});
document.getElementById("title").addEventListener("click", () =>{
processResponse(fetch("api/books?sortby=title"))
});
});
function processResponse(response) {
let table = document.getElementById("books");
let total = document.getElementById("total");
response.then(data => data.json())
.then(value => {
table.innerHTML = "";
const tr = document.createElement("tr");
let th = document.createElement("th");
th.innerHTML = "Author";
tr.appendChild(th);
th = document.createElement("th");
th.innerHTML = "Book Title";
tr.appendChild(th);
table.appendChild(tr);
for (let index = 0; index < value.books.length; index++) {
const book = value.books[index];
const tr = document.createElement("tr");
let td = document.createElement("td");
td.innerHTML = book.author;
tr.appendChild(td);
td = document.createElement("td");
td.innerHTML = book.title;
tr.appendChild(td);
table.appendChild(tr);
}
total.innerHTML = value.total;
});
}
server.js file
const fs = require('fs');
const express = require('express');
const app = express();
app.use(express.static("public"));
app.get("/", (req, res) => {
res.sendFile("index.html", { root: __dirname + "/public" });
});
const apiRouter = express.Router();
apiRouter.get("/books", (req, res) => {
let sortOrder = req.query["sortby"];
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
if (sortOrder === "author") {
books.sort((a, b)=> a.author.localeCompare(b.author));
} else if (sortOrder === "title") {
books.sort((a, b)=> a.title.localeCompare(b.title));
}
res.send(JSON.stringify({
books: books.slice(0, 50),
total: books.length
}));
});
})
apiRouter.get("/books/title", (req, res) => {
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
let titles = books.map(book => book.title);
res.send(JSON.stringify(titles));
});
})
apiRouter.get("/books/author", (req, res) => {
fs.readFile("data/books.json", { encoding: 'utf8' }, (err, data) => {
if (err) {
console.error("ERROR is: ", err);
return;
}
let books = JSON.parse(data);
let authors = books.map(book => book.author);
res.send(JSON.stringify(authors));
});
})
app.use("/api", apiRouter);
app.listen(8080, () => console.log('Example app listening on port 8080!'));
/*
And the books.json file that i guess you dont need so i wont post it.
My folder structure is:
Books > data Folder > books.json.
Books > public Folder > index.html.
Books > public Folder > index.js.
Books > server.js.
*/
Share
Improve this question
asked Feb 11, 2018 at 4:40
Happy CoconutHappy Coconut
1,0634 gold badges20 silver badges35 bronze badges
3
|
3 Answers
Reset to default 15Well this is what i had to do if it helps anyone in the future at all. This is all basic stuff but i am beginner so here we go. Open command prompt. Go to the destination of your project( where the index.js file is ) and write:
$ npm init -y
$ npm install -g express-generator
$ npm install express -S
$ npm install connect -S
$ npm install serve-static -S
then go to the destination of your server.js file and write
$ node server.js
After this i could run my page in browser typing http://localhost:8080/ in the URL.
If you are under Windows, create a new site in your local IIS (you should enable IIS in Windows components if not already) to your project folder. Then open http://localhost:8080 (or other port you can setup in the ISS for your new site)
Add to script tag type='text/javascript'
file://
URLs with ajax calls (for security reasons). You need to load your web page through a web server and make your ajax request through that web server using http:// or https://, not file://. – jfriend00 Commented Feb 11, 2018 at 5:39file://
to work and there is a way without using a server – Hashbrown Commented Jan 27, 2020 at 6:09