I currently have a CORS problem that I can't solve, here is my code:
gogologo.js
const souscription = async (req, res) => {
if (!req.body.data || !req.body.data.souscrireParams) {
console.error('souscription input error')
res.json({ data: { error: 'souscription input error' } })
return
}
const souscrireParams = req.body.data.souscrireParams
console.log('souscription:', JSON.stringify(req.body.data.souscrireParams))
var data = JSON.stringify(souscrireParams)
const headers = {
'x-api-key': apiKey,
'Content-Type': 'application/json'
}
var reqConfig = {
method: 'post',
url: 'url',
headers: headers,
data: data
};
console.log("reqConfig = ", reqConfig)
try {
const response = await axios(reqConfig)
const result = response.data
if (result.resultat === 'success') {
res.json({ data: result })
} else {
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription Fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: { message: 'souscrire error' } } })
}
} catch (error) {
console.log('error message : ', error.message)
console.log('error : ', error)
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>${JSON.stringify({ error: error.message })}`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: error.message } })
}
}
exports.souscription = souscription
index.js
exports.souscription = functions.runWith({
vpcConnector: 'app-functions-connector',
vpcConnectorEgressSettings: 'ALL_TRAFFIC'
}).https.onRequest(async (req, res) => {
console.log('souscription IP:', await publicIp.v4())
cors(req, res, async () => {
gogologo.souscription(req, res)
})
})
when I press the subscribe button, it displays an error message "Access to fetch at 'url genereted by firebase function' from origin 'url app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
with a post error.
Related
I am trying to send a DELETE request to my backend server, but I keep getting this response printed to my console:
Response {type: 'cors', url: 'http://localhost:3003/delete', redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3003/delete"
[[Prototype]]: Response
I don't know why this is happening.
server.js
const express = require('express')
const knex = require('knex')
const cors = require('cors')
const db = knex({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'postgres',
password: 'psql',
database: 'blogspot',
port: 5432
}
});
const app = express();
app.use(express.json())
app.use(cors())
// Delete Blog
app.delete('/delete', (req, res) => {
const {id} = req.body;
db.select('*').from('blogs')
.where({
id: id
})
.del()
.then(() => {
res.json('Deleted Successfully')
})
.catch(err => res.status(404).json('An error occured'))
})
fetchAPI.js
function deleteBlog (blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
}).then(resp => {
console.log(resp)
if (resp === 'Deleted Successfully') {
navigate(0)
} else if (resp === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
I keep getting 'ERROR' printed to my console along with the cors response I pasted above. When I refresh, I find that the blog has been deleted, but the response was definitely an error since navigate(0) wasn't run and ERROR was printed to my console. I have tried removing the 'Content-Type': 'application/json' header and sending the id as request params instead but I got the same error.
The fact that the response is of type "cors" just means that some contents are filtered by CORS policy (see https://developer.mozilla.org/en-US/docs/Web/API/Response/type) but you didn't get any error code, the statusCode is 200.
Since your response content type is JSON, you must also resolve the json parsing before reading the response:
function deleteBlog(blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
})
.then(data => data.json())
.then(resp => {
// I also suppose that you will more likely find
// your "Deleted successfully" in the resp.body property, so :
if (resp.body === 'Deleted Successfully') {
navigate(0)
} else if (resp.body === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
This question already has answers here:
'Access-Control-Allow-Credentials' header in the response is '' which must be 'true'
(2 answers)
Closed 2 years ago.
I am learning server-client communication in the course of making MMORPG project.
*update: server side code is edited.
This is server side code.
router.post('/login', async (request, response, next) => {
passport.authenticate('login', async (error, user) => {
try {
if (error) {
return next(error);
}
if (!user) {
return next(new Error('email and password are required'));
}
request.logIn(user, { session: false }, (err) => {
if (err) {.....
This is client side code
function postData(url, data = {}) {
return fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
body: JSON.stringify(data),
}).then((response) => response.json());
}
login() {
const loginValue = this.loginInpout.value;
const passwordValue = this.passwordInput.value;
postData('http://localhost:4000/login', { email: loginValue, password: passwordValue })
.then((response) => {
if (response.status === 200) {
this.startScene('Game');
} else {
console.log(response.message);
window.alert('invald username or password');
}
}).catch((error) => {
console.log(error.message);
window.alert('invald username or password');
});
}
when login() function is called, fetch() function throws this message in browser console.
(http://localhost:4000/login) is server side and (http://localhost:8000) is client side.
Access to fetch at 'http://localhost:4000/login' from origin 'http://localhost:8000'
has been blocked by CORS policy: Response to preflight request doesn't pass access
control check: The value of the 'Access-Control-Allow-Credentials' header in the
response is '' which must be 'true' when the request's credentials mode is 'include'.
LoginScene.js:48 POST http://localhost:4000/login net::ERR_FAILED
Failed to fetch <<-- fetch error message on browser console
I tried to fix it many different ways with no good outcome.
Try the following code:
import express from "express";
import http from "http";
const app = express();
const server = http.createServer(app);
const sio = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});
sio.on("connection", () => {
console.log("Connected!");
});
I am facing some issue while downloading file using node.js. I have scenario like my angular component is sending the file request. in my first node server I am doing the token validation and then redirecting to another node server where actually the execution happens. I am explaining my code below.
service.ts:
submitAndDownloadFile(formdata : any ){
const token = localStorage.getItem('token')
let headers = new HttpHeaders({
Authorization: 'Basic ' + token
})
const cecID = localStorage.getItem('cec');
const AppUrl = `${environment.nodeJsBaseUrl}:${environment.hostingNodeJsContainerPort}/convert-test-cases/${cecID}`;
return this.httpClient.post(AppUrl, formdata, { responseType: 'blob', observe : 'response', headers : headers});
}
Here I am sending the request to my first node.js server which code has given below.
app.js(first:port-8000):
router.post('/convert-test-cases/:id', middleware.auth, (req, res) => {
try{
let postRequestOptions = {
url: '',
method: 'POST',
json: true,
headers: {},
body: {},
};
postRequestOptions.url = 'http:localhost:9000/convert-test-cases';
postRequestOptions.headers = {
'Content-Type': 'application/json',
};
postRequestOptions.body = req.body;
request(postRequestOptions, async (error, response, pathList) => {
if(error) {
console.log('error', error);
}else{
res.send(pathList);
}
})
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here I am doing the token validation using middleware.auth and sending same request to another node.js file which code is explained below.
app.js:(second-port-9000):
router.post('/convert-test-cases', async (req, res) => {
try{
let response = await ctcCtrl.convertTestCase(req.body, req.files);
if(response.status == 'success'){
res.set('Access-Control-Expose-Headers','*, Content-Disposition');
return res.download(response.fileName,response.fileName);
}else{
return res.send(response);
}
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here only I am doing some execution and downloading the file. If I am connecting angular to node-9000 its working fine but my requirement is first I have to connect to port-8000 to some token validation and after that I have to send same req.body and re.file to app.js which is running in 9000 using request module. As per my code its not working at all.
I have tried to send, with Google API and Axios, a new email:
async SendMail (req, res) {
try {
const email = `From: ${req.body.sender}\r\n` + `To: ${req.body.receiver}\r\n` + `Subject: ${req.body.subject}\r\n\r\n` + req.body.message
const response = await axios.post(`https://www.googleapis.com/upload/gmail/v1/users/${req.body.userId}/messages/send`, email, {headers: {Authorization: `Bearer ${req.body.token}`, 'content-type': 'message/rfc822'}})
res.status(200).send({data: response.data, status: 'ok'})
} catch(err) {
console.log('error => ', err)
res.status(404).send({
error: 'Error for the recuperation of Google info'
})
}
}
It tells me I am unauthorised but I have added the correct scopes.
error: {
response: {
status: 401,
statusText: 'Forbidden',
...
}
}
The accessToken is working I have done a call with a get with it and it worked pretty fine.
This is my scope: https://mail.google.com/
I'm using node.JS with request module.
My problem is, I need to authenticate the user on every request because the session is destroyed outside of the .then((response) => {}) block.
How is it possible to save the created session in a class for later use?
I tried out everything without success.
Here is a not working code snippet
login() {
const getLoginUrl = 'https://www.demourl.com/'
const postLoginUrl = 'https://www.demourl.com/account/login/'
rp({
url: getLoginUrl,
jar: this.cookieJar,
method: 'GET'
})
.then((body) => {
var csrftoken = this.cookieJar.getCookies(getLoginUrl)[1].toString().split('=')[1].split(';')[0];
var args = {
url: postLoginUrl,
json: true,
method: 'POST',
data: {
username: this.username,
password: this.password
},
headers: {
'method': 'POST',
'path': '/account/login/',
'cookie': 'csrftoken=' + csrftoken,
},
jar: this.cookieJar,
resolveWithFullResponse: true
}
rp(args)
.then((response) => {
//Here is a valid session
//But how can I use this session in different functions?
console.log('Post demourl.com/account/login success');
})
.catch((error) => {
console.log('Post demourl.com/account/login error: ', error);
});
})
.catch((error) => {
console.log('Get demourl.com error: ', error);
});
}
you should use this function as a middleware and then attach what ever you want to attach in to your req
try in you main script do
'use strict'
const express = require('express');
const login = require('./login');
const app = express()
app.use(login);// use this if you want all your routes to check login or put it in a specific route
app.get('/', (req,res)=>{
//this route is only for loged in users
});
const server = http.createServer(app).listen(process.env.PORT);
module.exports = app;
and in your login script
const login = (req, res, next) => {
const getLoginUrl = 'https://www.demourl.com/'
const postLoginUrl = 'https://www.demourl.com/account/login/'
rp({url: getLoginUrl, jar: this.cookieJar, method: 'GET'})
.then((body) => {
var csrftoken = this.cookieJar.getCookies(getLoginUrl)[1].toString().split('=')[1].split(';')[0];
var args = {
url: postLoginUrl,
json: true,
method: 'POST',
data: {
username: this.username,
password: this.password
},
headers: {
'method': 'POST',
'path': '/account/login/',
'cookie': 'csrftoken=' + csrftoken,
},
jar: this.cookieJar,
resolveWithFullResponse: true
}
rp(args)
.then((response) => {
res.loginResponse = response; // save the response for later use
console.log('Post demourl.com/account/login success');
next();
})
.catch((error) => {
console.log('Post demourl.com/account/login error: ', error);
return res.send(error) //send the error
});
})
.catch((error) => {
console.log('Get demourl.com error: ', error);
return res.send(error) //send the error
});
}
module.exports = login
I never see this.cookieJar being defined. Make sure it's initialized somewhere:
this.cookieJar = request.jar();
If you only use a single cookieJar in your application, you could also use Request's global cookie jar by setting the option jar to true:
// Either by setting it as the default
const request = require('request').defaults({jar: true});
// Or by setting it on each request
request('www.example.com', { jar: true });