I'm following a Node.js course with refresh tokens and in some part of the code I started getting this error and I couldn't figure out what might be causing it.
I followed the course and my requests always worked well, but there was a class where the tutor needed to modify some parts of the code. I grabbed the files from GitHub to see what changed and modified my code as well. But from then on my postman requests didn't work anymore.
On Postman I have this error message
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /usuario</pre>
</body>
</html>
In my VS Code terminal the API is working normally.
My server.js file is
require('dotenv').config()
const app = require('./app');
const port = 3000;
require('./')
require('./database');
require('./redis/blocklist');
const routes = require('./rotas');
routes(app);
app.listen(port, () => console.log("A API está conectada!"))
My routes.js code is
const posts = require('./src/posts');
const usuarios = require('./src/usuarios');
module.exports = app => {
posts.rotas(app);
usuarios.rotas(app);
};
My user-routes.js code is
const usuariosControlador = require('./usuarios-controlador');
const middlewaresAutenticacao = require('./middlewares-autenticacao');
module.exports = (app) => {
app.route('/usuario/login')
app.post(middlewaresAutenticacao.local, usuariosControlador.login);
app.route('/usuario/logout')
app.get(middlewaresAutenticacao.bearer, usuariosControlador.logout);
app.route('/usuario')
app.post(usuariosControlador.adiciona)
app.get(usuariosControlador.lista);
app.route('/usuario/:id')
app.delete(middlewaresAutenticacao.bearer, usuariosControlador.deleta);
};
My code is on GitHub: https://github.com/Stephani0106/Seguranca-com-NodeJS
And my tutor's code is: https://github.com/alura-cursos/blog-do-codigo-2
Related
You must GET the "candidates/2021_05/mohamed_nagy_b3b03cbe" resource from a website service:
https://hire.verkata.com/askme/
Make the GET request above appear as if you're sending it by following a link to the resource from http://google.com/candidates/mohamed_nagy using a Chrome browser running on an Android Phone. Otherwise, the web service will give you an Access Denied error.
can anyone give me some guidance on how we can do some tasks like that in android, while I didn't do so before, please?
Note: I am using pure JavaSacript fetch API but can't solve the puzzle, Unfortunately.
client index.js
let button = document.getElementById('generate');
let Info = document.querySelector('Info');
const key = 'candidates/2021_05/mohamed_nagy_b3b03cbe';
const url = 'https://hire.verkata.com/askme/';
button.addEventListener('click', () => {
fetchWeather(url, key)
.then((data) => {
postData('/', {
Information: data.content(),
})
}).then(() => {
updateUI();
})
});
const fetchWeather = async (url, key) => {
const res = await fetch(url + key)
try {
const data = await res.json();
console.log(data);
return data;
} catch (error) {
console.log("Error:", error) // appropriately handle the error
}
};
const postData = async (url = '', data = {}) => {
console.log(data)
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json();
console.log(newData);
return newData
} catch (error) {
console.log('Error', error);
}
};
const updateUI = async () => {
const request = await fetch('/all');
try {
const allData = await request.json();
console.log(allData);
document.getElementById('info').innerHTML = allData.Info;
} catch (error) {
console.log('error', error);
}
};
server.js
let projectData = {};
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
const fetch = require('node-fetch');
app.use(express.static('website'));
const port = 8888;
app.listen(port, () => {
console.log(`server is running on localhost port number: ${port}`)
});
app.post('/', (req, res) => {
console.log(req.body)
const newEntry = {
Info: req.body.Information,
}
projectData = newEntry // projectData.push(newEntry)
res.send(projectData)
});
app.get('/all', (req, res) => {
console.log(projectData);
res.send(projectData);
});
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch API</title>
<link href="https://fonts.googleapis.com/css?family=Oswald:400,600,700|Ranga:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div id = "app">
<div class ="holder">
<div class="button" id="generate">Send Get Info</div>
</div>
<div class ="entry">
<div class = "title">Most Recent Entry</div>
<div id = "Holder">
<div id = "Info"></div>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
the server just telling me can't get because of 404 not fount on this server
You don't need a server side code. Actually you don't need to write any code to make a GET request.
You can use API Client tools such as Postman.
The request should be in this format:
method: GET
Referer: "http://google.com/candidates/mohamed_nagy",
User-Agent: "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Mobile Safari/537.36"
(User-Agent is required to simulate a Chrome browser running on an Android Phone.)
So, you can get a response, "You need to retrieve the puzzle within 72 hours of receiving the email".
You need to use three things to solve this puzzle.
Get method
User Agent
Referrer
You can find the sample Python Code below.
import requests
url = "https://hire.verkata.com/askme/candidates/2021_05/mohamed_nagy_b3b03cbe"
""" https://www.whatismybrowser.com/guides/the-latest-user-agent/android """
headers = {'user-agent': 'Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.99 Mobile Safari/537.36',
'Referer':'http://google.com/candidates/mohamed_nagy'
}
response = requests.get(url, headers=headers)
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.content, "html.parser")
print(soup.prettify())
There's a few things you can improve here and there. It seems like it's a student exercice and the subject doesn't specify the methods you should use to implement your solution, so let's go the fastest route.
You don't need server-side code
You must GET the "candidates/2021_05/mohamed_nagy_b3b03cbe" resource
from a website service: https://hire.verkata.com/askme/ Make the GET
request above appear as if you're sending it by following a link to
the resource from http://google.com/candidates/mohamed_nagy using a
Chrome browser running on an Android Phone. Otherwise, the web service
will give you an Access Denied error.
The subject doesn't say what you have to do with the data fetched to the URL https://hire.verkata.com/askme/ so I'll assume you just have to display them.
In this case, you don't need your whole server.js file. Express.js is a web framework to build all kinds of things, especially APIs and web apps, but since you don't seem to need routing nor back-end app in any way, you can just scrape it.
Acceptable HTML/JS
Again, as the subject doesn't mention anything (and since it probably won't be used in any kind of production environment), you can just put all your code in a single HTML file and it'll work just as expected.
Here's what I would do. (Keep in mind that the code below is not professional at all, and we go the fastest route, hence the acceptable in heading)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch API</title>
<link href="https://fonts.googleapis.com/css?family=Oswald:400,600,700|Ranga:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div id="app">
<div class="holder">
<button class="button" id="call-server">Send Get Info</button>
</div>
<div class="entry">
<div class="title">Most Recent Entry</div>
<div id="holder">
<div id="display-info"></div>
</div>
</div>
</div>
</body>
<script>
let button = document.getElementById('call-server');
let info = document.getElementById('display-info');
const key = 'candidates/2021_05/mohamed_nagy_b3b03cbe';
const url = 'https://hire.verkata.com/askme/';
button.addEventListener('click', () => {
fetchWeather(`${url}${key}`)
.then((data) => {
console.log(data);
info.innerHTML = data;
}).catch((err) => {
console.error(err);
})
});
const fetchOpts = { method: 'GET',
referrer: "http://google.com/candidates/mohamed_nagy",
};
const fetchWeather = async (fullUrl) => {
try {
const res = await fetch(fullUrl, fetchOpts)
return await res.json();
} catch (error) {
console.log("Error:", error) // appropriately handle the error
}
};
</script>
</html>
I took your code and simplified it. No need for a <a> tag, that would redirect you to the link you give it in the href attribute. What they meant by
Make the GET request above appear as if you're sending it by following a link to the resource from http://google.com/candidates/mohamed_nagy
is setting the referrer header in the request. More info on this here and here.
But it still doesn't work as of the time of this answer, and here's (partially) why.
What THEIR problem is
When navigating with a browser to the full URL you gave in your post, we can see that an error pops-up directly from PHP:
Notice: Undefined index: HTTP_REFERER in /var/www/html/hire/actions/requests.php on line 34
What this error tells is that the server couldn't find the header referer in the request. As this answer states, the referer header is not guaranteed to be sent by the browser.
Unfortunately, the same error pops whether the referer header is set or not. I tried almost all the combinations of referrer and referrerPolicy and it seems it never let me access anything.
In any case, it is an uncaught error on their side and this error should never be displayed to the end user no matter what.
Conclusion
Try double-checking the URL you try to reach to see if there's any typo. If you're 100% sure of the URL, try contacting the owner or developer of https://hire.verkata.com and tell them they have an uncaught error while checking the referer header.
Try chaning this in your HTML code add this
<div class="button" id="generate">Send Get Info</div>
instead if this in the address :
<div class="button" id="generate">Send Get Info</div>
to this
<div class="button" id="generate">Send Get Info</div>
or just change the href attribute to
href="#"
I am working on a project to manage printers with CUPS command-line, I have multiple "api's" that make different thinks, for now i just want so see my parsed JSON result in a view, but I'm clueless on how to pass that value trough Express and then render it in a EJS view:
my api:
const spawnSync = require("child_process").spawnSync;
const parseStdout = require('../utils/utils.js');
function lpstat(){
let printerList = spawnSync("lpstat -p", {
timeout: 10000,
encoding: "utf-8",
});
let parsedList = parseStdout(printerList);
let onlyPrinterList = parsedList.filter(function (line) {
return line.match(line.match(/^printer/) || line.match(/^impressora/));
});
let onlyPrinterNames = onlyPrinterList.map(function (printer) {
return printer.match(/(?: \S+)/)[0].trim();
});
process.on('exit', (code) => {
process.kill();
});
//this is what i want to pass to the view
return JSON.stringify(onlyPrinterNames);
}
my app.js
const express = require('express');
const app = express();
app.listen(3000);
app.set('view engine', 'ejs');
app.get('/lpstat',(req,res) => {
//what should i use here?
res.render('lpstat')
});
my lpstat.ejs
<html lang="en">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>lpstat</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<p>lpstat result:</p>
<%= what should i use here?%>
</body>
</html>
The second parameter in res.render defines the data that is given to your templates:
app.get('/lpstat',async (req,res) => {
// Call your api here to fill the variable
const printers = lpstat()
res.render('lpstat', {
printers
})
});
You will be able to use this in your ejs template then
<p>lpstat result:</p>
<%= printers %>
You will need to replace callApi with whatever function is used to fetch your data. I used async/await for a simpler answer, can be done with callbacks as well.
I'm trying to move a tensorflow model from its original html into a react app (built with create-react-app).
My App.js looks like this:
import logo from './logo.svg';
import * as tf from "#tensorflow/tfjs";
// import { loadImageclassification } from "#tensorflow/tfjs";
import './App.css';
import * as automl from "#tensorflow/tfjs-automl";
import * as modelJSON from './model.json';
function App() {
var loadFile = function(event) {
var image = document.getElementById('output');
image.src = URL.createObjectURL(event.target.files[0]);
run();
};
async function run() {
console.log(modelJSON);
// const model = await tf.loadImageclassification('model.json');
const model = await automl.loadImageClassification(modelJSON);
const image = document.getElementById('output');
const predictions = await model.classify(image);
console.log(predictions);
const pre = document.getElementById('result');
pre.textContent = JSON.stringify(predictions, null, 2);
}
return (
<div className="App">
<div className="hero-text">
<h1>classifier</h1>
<h3>Upload a picture to see what type it is! </h3>
<p>
<input type="file" accept="image/*" name="image" id="file" onChange={loadFile} />
</p>
<div id="demobox">
<p>
<label htmlFor="file">Upload your image</label>
</p>
</div>
<p><img id="output" width="200" alt="output" /></p>
<div className="result" id="result">
</div>
</div>
</div>
);
}
export default App;
My index.html looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
I am getting the following error, which seems to be issuing from somewhere in the loadImageClassification method:
Unhandled Rejection (TypeError): modelUrl.lastIndexOf is not a function
Edit:
Apparently loadImageClassification uses a fetch request under the hood and so requires a remote file (which is strange, because it seemed to work fine in the static index.html original version of this same project).
So I am now trying it just with a localhost express server, which at present looks like this:
const modelJSON = require('./model.json');
const express = require("express");
const bodyParser = require("body-parser");
const CORS = require("cors");
const app = express();
app.use(bodyParser.json());
app.use(CORS());
let modelObj = modelJSON;
app.get("/", (req, res) => {
// console.log(modelObj);
res.send(modelObj);
});
app.listen(5000, () => {
console.log("Server listening on port 5000");
});
I can see the correct data when I navigate to localhost5000, but when I change
async function run() {
const model = await automl.loadImageClassification(modelJSON);
to
async function run() {
const modelUrl = "http://localhost:5000/";
const model = await automl.loadImageClassification(modelUrl);
I get these errors:
Edit 2:
My server.js file now looks like this:
This produces the same errors as in the previous screenshot. (I am leaving in the comments that mess of an attempt to include all the shard files in this server.js file screenshot just because it may illustrate that I don't understand how to pass those ancillary model files to loadImageClassification when it makes its fetch request.)
So presumably the problem now has to do with the fact that loadImageClassification assumes that the ...shard__of6.bin and dict files are in the same directory as the model.json file.
So the question may (?) be: how to simulate the file structure that it (i.e., loadImageClassification) is expecting within a remote node server.
Fundamental confusion:
I'm don't understand why, when loadImageClassification is in the original static html, it does not seem to require a remote url from which to fetch model.json — but then when I put it in my react app, it suddenly gives me this error: "Fetch API cannot load file:///Users///client/src/model.json. URL scheme must be 'http' or 'https' for CORS request."
What's the location of the model on your local device?
Try changing
const modelUrl = "http://localhost:5000/"
to
const modelUrl = 'model/model.json'
if the model is in build/model/, or to whatever the location is.
I've been through A LOT of issues in here about this topic but so far no answers has been the solution for my problem.
My setup is an AWS EC2 server with apache installed. I've installed node.js in the /node folder containing a server-file called server.js and in the root folder I have my client-file index.php. I have Let´s Encrypt SSL-certificates for my domain and therefore I need everything to run over https. I have opened up the port 3000 for all traffic en AWS.
Server.js
const app = require('express')();
const fs = require('fs');
const options = {
key: fs.readFileSync("/etc/letsencrypt/live/example.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/example.com/fullchain.pem")
};
const http = require('https').Server(options, app);
const io = require('socket.io')(http);
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
});
});
http.listen(3000, function(){
console.log('listening on 3000');
});
index.php
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket Test</title>
</head>
<body>
<ul id="events"></ul>
<script src="https://cdn.jsdelivr.net/npm/socket.io-client#2/dist/socket.io.js"></script>
<script>
const events = document.getElementById('events');
const newItem = (content) => {
const item = document.createElement('li');
item.innerText = content;
return item;
};
const socket = io('https://example.com:3000', {transports: ['websocket', 'polling']});
console.log(socket);
socket.on('connect', () => {
console.log("did connect");
events.appendChild(newItem('connect'));
});
socket.on('disconnect', () => {
console.log("did disconnect");
});
</script>
</body>
</html>
The problem
When I start my node server everything seems right. Executing node server.js returns listening on 3000 as supposed. When I go to index.php it never returns did connect BUT when I then exit the server node I get the did disconnect message in the browser console.
Also the server never returns anything else but listening on 3000.
Please help me :-)
Since the recent update to v3.0.0, version 2.x.x clients are not compatible so won't be able to connect.
The fix is to make sure both client and server are using the same versions, or use the server served version /socket.io/socket.io.js (which is not always possible, webpack etc)
Related issue on github: https://github.com/socketio/socket.io-client/issues/1390
I've been trying to learn NodeJS following
this NodeJs Youtube Tutorial.
I already worked with the Fetch API for a couple of months to get data from WordPress and Google Sheets back ends.
The last videos of the Youtube playlists are about creating a To Do List app with NodeJS and the npm's express, EJS and body-parser.
However, at part 4 of the To do list app, this "teacher" is using jQuery with Ajax to POST data to NodeJS (His jQuery Code Snippet). Since I've only been working with fetch() for AJAX POST requests, i wanted to continue with this method in plain JavaScript.
My ejs file, called todo.ejs, storing the HTML Template of the page looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/assets/style.css">
<!-- Works because of express middleware.
Since we stored the public folder as a static folder,
we can request anything within that folder from the url, such as
127.0.0.1:3000/assets/styles.css
-->
<title>Todo List</title>
</head>
<body>
<h1>My Todo List</h1>
<div id="todo-table">
<form>
<input type="text" name="item" placeholder="Add new item..." required>
<button type="submit">Add Item</button>
</form>
<ul>
<% todos.forEach(todoList =>{ %>
<li> <%= todoList.item %> </li>
<% }) %>
</ul>
</div>
</body>
<script src="/assets/script.js"></script>
</html>
My script.js (linked to the todo.ejs page) looks like this:
document.addEventListener("DOMContentLoaded", function (event) {
let submitButton = document.querySelector("button");
let textField = document.querySelector("input");
submitButton.addEventListener("click", addItem);
function addItem() {
let newItem = textField.value;
let todo = {
item: newItem
};
fetch("/todo", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(todo)
}).then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.log(err))
}
});
And my controller handling all get/post requests, called todoController.js, looks like this:
let bodyParser = require("body-parser");
let urlencodedParser = bodyParser.urlencoded({ extended: false });
// Have some items already in place
let data = [{item: "Get milk"} , {item: "Walk dog"} , {item: "Clean kitchen"}];
module.exports = function (app) {
//Handle get data requests
app.get("/todo", function (req, res) {
res.render("todo", {todos: data});
});
//Handle post data requests (add data)
app.post("/todo", urlencodedParser, function (req, res) {
console.log(req.body);
});
//Handle delete data requests
app.delete("/todo", function (req, res) {
});
};
Now, every time i populate the input field with some text and hit the enter button, my terminal outputs empty objects:
Based on those empty objects, there has to be something wrong that my POST requests are not accepted/sent correctly.
My file tree looks like this:
Anyone who maybe has (probably an obvious) answer to this?
(I know I could just grab his jQuery Ajax code snippet to make it work, but I'm eagerly trying to understand it using plain Javascript)
Thanks in advance to everyone taking time to help me :)
You need to use bodyParser.json instead of bodyParser.urlencoded.
As the names imply, urlencoded will parse url parameters while bodyParser.json will parse json in the body of the request.
I had the same problem but my express's version was > 4.5 so i used :
const express = require('express');
app = express()
app.use(express.json({
type: "*/*"
}))
instead of :
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json())
the problem was fixed by using the parameter {type : '/'} to accept all received content-types.