fastify set reply headers for all routes - fastify

For every route I have to type the same headers as shown below. Is there a way to set these headers globally so that they are used by default for every route and can be overridden on a per-route basis?
fastify.post("/api/users", async (request, reply) => {
try {
reply
.code(200)
header("Access-Control-Allow-Origin", "http://localhost:3000")
.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
.header("Content-Type", "application/json; charset=utf-8")
.send();
} catch (error) {
reply
.code(400)
.header("Access-Control-Allow-Origin", "http://localhost:3000")
.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
.header("Content-Type", "application/json; charset=utf-8")
.send();
}
});

You can set some headers before use send()
fastify.addHook('preHandler', (req, repy, done) => {
reply.header("key", "value")
done()
})
fastify.post("api/users", async (req, reply) => {
try {
reply.code(200).send()
} catch (err) {
reply.code(400).send()
}
})
But I saw you want to use CORS, why not use fastify-cors ?

Related

CORS related problem, i cannot proceed to a POST request

I'm having some troubles trying to make my backend and front communicate to each others (reactjs + vanilla NODEjs), both on different localhost port (4000 and 3000)
I managed to make it work until i wanted to try to add data to my database.
I can GET data with my react app but i can't POST any data.
Here is the code for both sides :
front :
`
const sendData = async (event: any): Promise<void> => {
console.log("hello");
event.preventDefault();
const response = await fetch(`${_DATA_URL_}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(employeeForm),
});
const data = await response.json();
console.log(data);
};
`
back :
const Router = (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Content-Type, Accept, Origin, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, PATCH, OPTIONS"
);
console.log("hello"); //debug
if (req.method === "GET") {
if (req.url === "/api/employees") {
getEmployees(req, res);
} else if (req.url.match(/\/api\/employees\/(\w{4}-?){3}/)) {
const requestID = req.url.split("/")[3];
getEmployee(req, res, requestID);
} else {
res.statusCode = 404;
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ message: `Error : ${req.url} not found !` }));
}
}
if (req.method === "POST") {
if (req.url === "/api/employees") {
createEmployee(req, res);
} else {
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ message: `Error : ${req.url} not found !` }));
}
}
if (req.method === "DELETE") {
if (req.url.match(/\/api\/employees\/(\w{4}-?){3}/)) {
const requestID = req.url.split("/")[3];
deleteEmployee(req, res, requestID);
} else {
res.statusCode = 404;
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ message: `Error : ${req.url} not found !` }));
}
}
if (req.method === "PUT") {
if (req.url.match(/\/api\/employees\/(\w{4}-?){3}/)) {
const requestID = req.url.split("/")[3];
updateEmployee(req, res, requestID);
} else {
res.statusCode = 404;
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ message: `Error : ${req.url} not found !` }));
}
}
};
i'm pretty sure it comes from react side because posting data works fine when i use POSTMAN, and after a while on localhost i receive this error in the console :
Maybe i'm using cors incorrectly, anyways thanks for your futures answers
I figured it out,
answer here (in french) and here

Get HTTP request body data using Node.js

The frontend is index.html:
axios.post('http://localhost:1337/', {
clientId: document.getElementById('clientId').value,
cmd: document.getElementById('cmd').value,
type: document.getElementById('type').value,
amt: document.getElementById('amt').value,
merchantRef: document.getElementById('merchantRef').value,
channel: document.getElementById('channel').value,
successUrl: document.getElementById('successUrl').value,
failureUrl: document.getElementById('failureUrl').value,
webhookUrl: document.getElementById('webhookUrl').value,
goodsName: document.getElementById('goodsName').value
})
.then(function (response) {
var json = response.data;
document.getElementById('sessionId').innerHTML = json['sessionId'];
SpiralPG.init(json['sessionId']);
})
.catch(function (error) {
console.log(error);
});
The backend is server.js:
http.createServer(async function (req, res) {
try {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST');
res.setHeader('Access-Control-Allow-Headers', '*');
const buffers = [];
for await (const chunk of req) {
buffers.push(chunk);
};
const data = Buffer.concat(buffers).toString();
saleSession(res, data);
}
catch (error) {
console.log(error);
}
}).listen(port);
something inside function saleSession(); in the server.js to get the data from frontend(if I hard code in here, there will be no error, but change to input data from frontend, there will be error):
var merchantRef = JSON.parse(data).merchantRef;
let bodyData =
{
'clientId': JSON.parse(data).clientId,
'cmd': JSON.parse(data).cmd,
'type': JSON.parse(data).type,
'amt': JSON.parse(data).amt,
'merchantRef': merchantRef,
'channel': JSON.parse(data).channel,
'successUrl': JSON.parse(data).successUrl,
'failureUrl': JSON.parse(data).failureUrl,
'webhookUrl': JSON.parse(data).webhookUrl,
'goodsName': JSON.parse(data).goodsName
}
I'm just copy the code in https://nodejs.dev/learn/get-http-request-body-data-using-nodejs, which is node.js office website. Why the output is:
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at saleSession (C:\Users\JoeChan\Desktop\my-nodejs2\server.js:41:28)
at Server.<anonymous> (C:\Users\JoeChan\Desktop\my-nodejs2\server.js:104:9)
at processTicksAndRejections (node:internal/process/task_queues:96:5)

Cross Server user not receiving the actual value of cookies

I am trying to send/retrieve cookies from one system to another system.
Here is my FE code (Angular 4) for setting a cookie
document.cookie = 'student_exists=true;SameSite=None;Secure'
// it will be true or false depending upon whether the student exists or not.
this is my route in node.js -> xx.com/api/retrievecookie
This is my function
retrievecookie () {
try {
let student_exists = false;
if (req.cookies && req.cookies.student_exists &&
req.cookies.student_exists === 'true') {
student_exists = true
}
const data = {'student_exists': student_exists};
res.json(data);
} catch (e) {
console.log(e);
res.send({'error': 'error in your request'});
}
}
Here is my index file (node js)
const cookieParser = require('cookie-parser');
app.use(function (req, res, next) {
console.log(req);
const origin = req.headers.origin;
if (req.url === '/api/studentprofile/verify') {
res.setHeader('Access-Control-Allow-Origin', origin);
} else {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
When I am hitting the URL & same browser from my own system, I am getting the true values i.e. either true or false.
When the other user with different server or browser, ther user is always getting false,
Here is other user's code
> $.ajax({
> type: "GET",
> url: "xx.com/api/retrievecookie",
> xhrFields: {
> withCredentials: true
> },
> success: function(data) {
> console.log(data);
> },
> error: function(data) {
> alert(data);
> }
});
please help me fix this issue.

"\" in JSON response

So my app gets data from my database but it send a response with " \ "
Express response
[
{
"ID": "account-saassan",
"data": "{\"uuid\":\"saassan\",\"username\":\"sasasasasa\"}"
}
]
Console output:
[
{
ID: 'account-saassan',
data: '{"uid":"saassan","username":"sasasasasa"}'
}
]
Code:
const UserData = new db.table("userdata")
app.use((req, res, next) => {
res.append('Access-Control-Allow-Origin', ['*']);
res.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.append('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.get("/list", (request, response) => {
let data = UserData.all()
console.log(data)
response.type('json');
response.json(data)
// I've tried with response.send too. And without response.type
})
app.listen(8080)
Why does it add "" in the response and how do I fix it?
Try to using JSON.stringify
response.json(JSON.stringify(data))
Add please add this :
response.setHeader('Content-Type', 'application/json');

Acessing request body without using Express Nodejs

So I am trying to access the body of a request I am sending. I don't want to incorporate Express for this project. I understand that I essentially have to stream the body in from the incoming request, however it seems that my approach isn't pulling any data from the request. Here is what I have
The request
var query = document.getElementById('search').value;
console.log(query);
axios({
method: 'get',
url: url,
headers: {},
data: {
query: query
}
}).then((response) => {
if(response.status == 200){
console.log(response);
this.tweet = response;
}
}).catch((error) => {
console.log(error);
});
Where I am handling the request
http.createServer((req, res ) => {
//Setting CORS Headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if ( req.method === 'OPTIONS' ) {
res.writeHead(200);
res.end();
return;
}
else if(req.url == "/search"){
let body = 'Our Data: ';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
console.log(body);
});
//console.log(data);
callTweetAPI.callTweetAPI(function(response) {
res.write(JSON.stringify(response));
res.end();
});
}
}).listen(port);
The output I expect would be the data I sent in the axios request so 'query', but I end up with blank output. It seems that the request being sent through doesn't have a data block available?

Resources