cors error when using onRequest cloud functions - node.js

This is my function
export const testFunction = functions.https.onRequest((req, res) => {
const text = req.body.text;
res.set("Access-Control-Allow-Origin", "*");
res.send({text: text});
});
i've tried using const cors = require('cors')({origin: true});
I keep getting this as a response. Does anyone know why?

Consider importing like this,
const cors = require('cors')({origin: true});
And try running the below function using firebase deploy –only functions :
const functions= require("firebase-functions");
const cors = require('cors')({origin: true});
exports.testFunction = functions.https.onRequest((req, res) => {
cors(req, res, () => {
const text = req.body.name;
res.send({text:text});
});
});
And then send request using :
curl -X POST "https:/region-projectID.cloudfunctions.net/function-name" -H "Content-Type:application/json" --data '{"name":"Keyboard Cat"}'
The output I am getting in the console is :
And when I click on the Cloud Function URL endpoint, my output is an empty {}.
If you try res.send(“Hello World”) in place of res.send({text:text}), you will get the output in the browser as Hello World but since our Cloud Function performs some contrived operation using data passed in the request body.This could result in an error at run time if the property name is null or undefined.
And indeed, if we deploy this new function and then attempt to call it from our web app without updating our request we do get an error. However, it might not be the error you’d expect.
It’d be easy to assume that we somehow misconfigured our CORS policy. Infact swapping cors() to cors({ origin: '*'}) to cors({ origin: true}) all to no avail. Only when we view the logs for our Cloud Function do we get a useful error message.
So try sending a POST request with the –data flag, or if you are using Postman, send the data and the parameters. Then only you would be able to have an output, if you still see the CORS error, check if your function is handled well or your nested request body attribute is not undefined/null. Sometimes CORS errors are not always CORS!

Related

How does the fetch api work with express when trying to send a json object

I have a system in place where I have a nodejs app:
app.post('/action', (req, res) => {
...
const option = req.body.option
...
switch (option) {
case 'getinfo':
objectToSend = {"foo": "bar"}
// i tried using
res.json(objectToSend)
// and
res.send(JSON.stringify(objectToSend))
// but neither got me anywhere
break
}
And a website that sends a post request using fetch like this (infoModal is the function I use to display data) (I got the action function sent on discord and have been using it since then, but ive never had to do anything with the response)
let action = async (i) => {
res = await fetch("/action", {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(i)
})
return await res.json
}
action({
option: 'getinfo'
}).then(j => {
infoModal(j.foo,'ok')
})
I can't really fix either the backend or frontend since both have to work for me to confirm it works...
EDIT:
These are my requires, uses and sets:
require('dotenv').config()
...
const express = require('express')
const path = require('path')
var bodyParser = require('body-parser')
let ejs = require('ejs')
const fs = require('fs')
var cookieParser = require('cookie-parser')
var colors = require('colors')
const app = express()
app.use(bodyParser.json())
app.use(cookieParser())
app.set('views', path.join(__dirname, 'frontend'))
app.set('view engine', 'ejs')
One obvious mistake is not executing the jeson() method of the Fetch response. And, although harmless, the second await statement is not really necessary - the async functions anyway wrap what is returned in a promise.
return res.json();
If that doesn't work -
See what your developer console says. It should give you lot of information about the request. If there is an error, follow the info (response code, any error message etc) and try to determine the problem.
Use a rest client such as POSTMAN to verify your backend first. When you know that it can respond well to a proper request, you can try your front-end with confidence and get more understanding on how the response should be handled.

Infinity nodeJS get/post request

So I'm trying to learn nodeJS.. But something wierd is happening. When I try to make a GET or a POST request it keep requesting infinitly on the localhost. I tested with a simple piece of code just requesting a simple Hello Word but it still doesnt works. It was working perfectly yesterday.
I tested insomnia, postman and the browser. If someone can help me would be very nice, cause I'm really stucked here...printscream of the insomnia infinity request
const {json} = require('express');
const express = require('express');
const {uuid} = require('uuidv4');
const app = express();
app.use(express,json);
const projects = [];
app.get('/projects', (request, response) => {
return response.json(projects);
});
app.post('/projects', (request, response) => {
const {title, owner} = request.body;
const project = {id: uuid(), title, owner };
projects.push(project);
return response.json(project);
});
app.listen(3333, () => {
console.log('Working 👏👏')
});
It's just two little mistakes. Take in mind that express.json() is a method, so you need to put it like this:
app.use(express.json())
You are using a comma instead of a point. However, you have done a destructuring of the .json () method; therefore, you do not have to prepend express; it would look like this:
app.use(json())
On the other hand, you probably have an unwanted result in the post request since you send the project variable instead of projects. Be sure that is what you want.

Browser not displaying JSON file - Setheader Nodejs

I'm trying to display a content on my browser as JSON file using the following code
const express = require ("express")
const app = express();
app.get("/test", async(req, res) => {
const rows = await actiondb();
res.setHeader("content-type", "application/json")
res.send(JSON.stringify(rows))
})
Even using the setheader and "content-type", "application/json" it is not working. The photo below shows the results
I was expecting to get something as:
What can be done?
Your browser doesn't natively format JSON responses like you're showing in your example. If you want to format the JSON response in your browser, the browser extension JSON Formatter can be installed into your browser. This will detect JSON/JSONP and display it for you formatted.
Example with the extension installed:
All this extension does is make the JSON response easier to read, it doesn't change the content type or data returned. Making a request to /test will work with or without the extension.
As a side-note, your code can be simplified to use express's .json() method:
const express = require ("express");
const app = express();
app.get("/test", async(req, res) => {
const rows = await actiondb();
res.json(rows);
});

JSON comes in undefined, where is the data lost?

I am using postman to test a rest API I'm building for a project. I'm trying to send some data to a post method, but the data is getting lost somewhere between Postman and the endpoint.
I've tried tracing the data with console logs, but nothing comes out (req.body is undefined). I'm pretty sure the issue isn't with the endpoint or router, as the same error comes up in postman as in the console of my IDE, which means there's some sort of communication.
// json I'm putting into postman. validated with Jsonlint.com
{
"Name": "testN",
"file": "file1",
"Path": "/home/userf",
"userName": "user1"
}
// profileWrite.js
const dbProfileWrite = require('../...db-ProfileWrite');
const bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
// my post method
async function post(req, res, next) {
try {
console.log("attempting to parse data: " + req.body);
let profile = req.body;
console.log("data parsed, writing profiles");
profile= await dbProfileWrite.writeProfile(profile);
res.status(201).json(profile);
} catch (err) {
next(err);
}
}
module.exports.post = post;
UPDATE 7/15/19:I have recreated a microversion of my project that is having this issue on stackblitz. there's some sort of package error that I'm working on, but here's the link. I've recreated the methodology I'm using in my project with the router and all and looked at the example in the express docs. hopefully this helps isolate the issue.The data still comes in undefined when I post to this api through postman, so helpfully this much smaller view of the whole project helps.
Assuming you are using Express framework, by the look of the post function. You need to use a middlewear function to process request body using body-parser. Make sure you are using the correct parser in this case
app.use(bodyParser.json())
You don't need body-parser anymore it was put back in to the core of express in the form of express.json, simply use app.use(express.json()).
To access the body of your request use req.body, it should come with a object with the keys representing the json sent;
var app = express();
app.use(express.json());
async function post(req, res, next) {
try {
console.log("attempting to parse data: " + req.body);
let profile = req.body; // no need to use any functions to parse it
console.log("data parsed, writing profiles");
profile= await dbProfileWrite.writeProfile(profile);
res.status(201).json(profile);
console.log("profilecreated");
} catch (err) {
next(err);
}
}
See the express documentation
Solved the issue myself with a little help from John Schmitz. The issue was that I was defining the router and the server before actually telling it how to handle json bodies/ objects, so the body came through as the default undefined. In my index.js, the following is what fixed the code:
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/api/v1', router);
the key to this is that the app is told to use json and express.urlencoded before the router is declared. these actions have to happen in this order, and all before app.listen is called. once the app is listening, all of its params are set and you can't change them. Tl;dr: node is VERY picky, and you HAVE to define these things in the right place. thanks all for the help.

Google Firebase Functions - Timeout when doing HTTP requests

So I am trying to make a simple proxy (I think that's the right word) and I've come up with some code that works fine locally. I can call 'firebase serve --only functions' and the function works fine and I get expected results. Now when I deploy this same code, and try calling it it just times out. I have no idea why, so I was hoping I could get some help.
Here's the code:
//Variables
const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors');
const request = require('request');
//App
const app = express();
app.use(cors({ origin: true }));
//Endpoints
app.get('/**', function(req, res) {
request('https://example.com' + req.url, function(err, proxyRes, body) {
//Err
if (err) {
res.send('Error: ' + err.code);
return
}
//Res
res.status(200).send(body);
});
});
//Functions
exports.proxy = functions.https.onRequest(app);
HTTP functions will time out if they don’t send a response. This means your request() is probably failing, and it’s probably failing because, on the free Spark payment plan, you can’t make outgoing requests to services that Google doesn’t fully control.
Your function should send a response in all conditions in order to avoid a timeout. This means you should be checking for errors all the time.

Resources