I'm trying to make a request to my localhost server but am getting the error Failed to load resource: net::ERR_CONNECTION_REFUSED.
Here is my front end code:
(async () => {
const data = await fetch('http://localhost:8080/articles/', {
headers: { "Access-Control-Allow-Origin": "http://localhost:8080/articles/" }
});
const articles = await data.json()
console.log(articles)
})();
and backend code:
app.get("/articles/", function (req, res) {
let inputValue = req.body.page;
let pages = Math.ceil(totalResults / 10)
page = scripts.iteratePages(inputValue, page, pages);
request("https://newsapi.org/v2/top-headlines?q=" + initialQ +
"&category=sports&pageSize=10&page=" + page + "&sortBy=relevance&apiKey=" +
apiKey, function (error, response, body) {
if (!error && response.statusCode == 200) {
let data = JSON.parse(body);
let articles = scripts.articlesArr(data);
res.json({ articles: articles });
} else {
res.redirect("/");
console.log(response.body);
}
});
});
I've done some research myself, which points to using my private IP address instead of localhost and am getting an ... is not a function error in the console:
let ipAddress = "blah.blah.blah.blah"
(async () => {
const data = await fetch('http://' + ipAddress + ':8080/articles/', {
headers: { "Access-Control-Allow-Origin": "http://" + ipAddress + ":8080/articles/" }
});
const articles = await data.json()
console.log(articles)
})();
Any help would be great.
I think the error was caused by cross domain issues. You make a misunderstanding about CORS headers. The headers are not used by request but response.
If javascript program is making a cross domain request, the browser will first send an OPTION request with same parameters to the server. If backend on the server consider the request is legal, a response with only CORS headers will be send back to the browser, and then the browser check the CORS header against current environment. If CORS headers are suitable, the browser will finaly send the real request to server, or throw an error otherwise.
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Related
I am trying to build a project in which I will fetch the user's step count by using the google fit Rest API. For this, I have created a project on google's developer console and specified a redirection url there. Have a look to the code snippet below :
exports.getUrl = async (req, res, next) => {
try {
const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_FIT_CLIENT_ID,
process.env.GOOGLE_FIT_CLIENT_SECRET,
process.env.GOOGLE_FIT_REDIRECTION_URL
);
console.log("oauth2Client", oauth2Client)
// generate a url that asks permissions for fitness activity scopes
const scopes = ["https://www.googleapis.com/auth/fitness.activity.read profile email openid"];
const url = oauth2Client.generateAuthUrl({
access_type: "offline",
scope: scopes,
include_granted_scopes: true,
state: JSON.stringify({
// callbackurl: req.body.callbackurl,
})
});
console.log("url", url);
res.redirect(302, url);
} catch (err) {
console.log("err", err)
next(err);
}
}
exports.getSteps = async (req, res, next) => {
try {
const queryUrl = new urlParse(req.url);
const code = queryParse.parse(queryUrl.query).code;
const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_FIT_CLIENT_ID,
process.env.GOOGLE_FIT_CLIENT_SECRET,
process.env.GOOGLE_FIT_REDIRECTION_URL
);
const token = await oauth2Client.getToken(code);
oauth2Client.setCredentials(token);
const result = await axios({
proxy: {
protocol: 'http',
host: 'proxy-url',
port: port
},
method: "POST",
headers: {
authorization: "Bearer " + token.tokens.access_token
},
"Content-Type": "application/json",
url: "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate",
data: {
"aggregateBy": [{
"dataTypeName": "com.google.step_count.delta",
"dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps"
}],
"bucketByTime": { "durationMillis": 86400000 }, // This is 24 hours
"startTimeMillis": startTime, // This startTime and endTime I am getting from DB
"endTimeMillis": endTime
}
});
if (result) {
const response = [];
let stepArray = result?.data?.bucket;
for (const dataSet of stepArray) {
for (const points of dataSet.dataset) {
for (const steps of points.point) {
response.push(steps?.value[0]?.intVal);
}
}
}
res.status(200).send(response);
} else {
throw new Error('Data fetching failed!');
}
} catch (err) {
next(err);
}
}
The steps url is what I have mentioned as a redirection url on the google's developer console. I have used proxy because the urls which are getting called are not whitelisted on the server on which I am deploying the code.
Now, everything worked perfectly fine in localhost but on server, I am getting below error :
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?access_type=offline' (redirected from 'https://someexample.com?id=123') from origin 'https://someexample.com' 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.
Also, one thing to note here is that the above error not coming when I am trying to get the data from chrome with --disable-web-security flag.
I have mentioned the uri through which this request is originating ( ex- https://someexample.com) in authorised JavaScript origins on the Google's developer console too.
Please let me know if I am doing something wrong. Any response would be highly appreciated.
I've handled my server side's basic auth with nodejs, Please refer the code below.
module.exports = basicAuth;
// require("dotenv").config({ path: "./.env" });
require("dotenv/config");
// async function basicAuth(req, res, next) {
function basicAuth(req, res, next) {
// check for basic auth header
if (
!req.headers.authorization ||
req.headers.authorization.indexOf("Basic ") === -1
) {
return res.status(401).json({ message: "Missing Authorization Header" });
}
console.log(req.headers.authorization);
// verify auth credentials
const base64Credentials = req.headers.authorization.split(" ")[1];
// console.log(base64Credentials);
const credentials = Buffer.from(base64Credentials, "base64").toString(
"ascii"
);
const [username, password] = credentials.split(":");
// const user = await userService.authenticate({ username, password });
let user = 0;
if (
username == process.env.API_USERNAME &&
password == process.env.API_PASSWORD
) {
user = 1;
}
if (!user) {
return res
.status(401)
.json({ message: "Invalid Authentication Credentials" });
}
next();
}
I've added app.use(cors()) in my app.js and I'm able to access all routes using basic authentication.
I've written my front end application using react and I'm using axios to fetch the data using the routes that I created. Please note the same API's work when I try to access it without using basic auth.
Below is the code for accessing data using axios.
try {
require("dotenv").config();
console.log(this.state.params);
let urlparam = "http://localhost:5000/users/" + this.state.params;
let result;
result = await axios({
url: "http://localhost:5000/users",
method: "get",
withCredentials: true,
headers: {
authorization: "Basic c2Fsb29uOnNhbG9vbg==",
},
});
} catch (err) {
console.log(err);
}
Using the above code I get:
The requested resource requires user authentication.
on Edge browser and on Google chrome I get the error:
Access to XMLHttpRequest at 'http://localhost:5000/users' from origin 'http://localhost:3000' 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.
and
xhr.js:178 GET http://localhost:5000/users net::ERR_FAILED
Please bear in mind I've added and used the cors middleware for all routes and it was working previously.
I even tried passing auth parameters separately like
auth:{username:"",password:""}
it still wont work
I had to include
app.use(basicAuth) below app.use(cors()) in the app.js file.
I am trying to access an api but when I access it in the browser, I get a CORS error. To get around this problem I set up an api proxy server. When this proxy gets a html request it connects to the browser blocked api and pulls the data needed. I think there is a problem on the proxy server where it is also blocking CORS and that needs to be changed, I’m not so sure. When I call the proxy api it gets the data from the browser blocked api and logs it to the console but does not push it to the browser because of the error below.
1.How do I correct this error “Reason: CORS header 'Access-Control-Allow-Origin' missing”
2.Should I be doing this a different way?
Error
Data being logged on the server
Server routing code - app.js
const apiCallFromRequest = require('./Request')
const apiCallFromNode = require('./NodeJsCall')
const apiCallFromTEST = require('./test.js')
const http = require('http')
http.createServer((req, res) => {
if(req.url === "/test"){
let start_time = new Date().getTime();
apiCallFromTEST.callApi(function(response){
//console.log(JSON.stringify(response));
res.write(JSON.stringify(response));
console.log(response);
console.log("Request API Requested");
console.log('API Test Time:', new Date().getTime() - start_time, 'ms');
res.end();
});
API proxy rought code -test.js
var rp = require('request-promise');
const callExternalApiUsingRequest = (callback) => {
var options = {
uri: 'https://app.invoiceninja.com/api/v1/products',
headers: {
'X-Ninja-Token': 'APIKEY'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function (data) {
console.log(data);
return callback(data);
})
.catch(function (err) {
// API call failed...
});
}
module.exports.callApi = callExternalApiUsingRequest;
website side - Just a basic fetch request
function gotProductData(){
fetch('http://localhost:3000/test')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
Try to install "cors" package (npm install cors) and import to app.js :
const cors = require('cors');
Run that above routes:
app.use(cors())
More details:
https://www.npmjs.com/package/cors#installation
HTTP post request is not sending body or param data to the server
Forgive me if this turns out to be a duplicate question. I've looked at several similar questions on stack overflow, but none of them have solved my problem. Also tried using a GET request instead of a POST request, but body data is still not sending.
Client side code:
// ionic code
homeUrl: string = 'http://localhost:80';
let obj = {"name": "Guest"};
let response = this.httpClient.post(this.homeUrl + '/admin-signup', JSON.stringify(obj));
response.subscribe(data => {
console.log('response: ', data);
//TODO: handle HTTP errors
});
Server side code:
server.post('/admin-signup', (req, res) => {
console.log('sign')
console.log(req.body);
// TODO: Process request
res
.status(200)
.send(JSON.parse('{"message": "Hello, signup!"}'))
.end();
});
First of all, import http client
import { HttpClient, HttpHeaders } from '#angular/common/http';
Then do the following
const header = new HttpHeaders({
'Content-Type': 'application/json',
Accept: 'application/json'
//api token (if need)
});
const options = {
headers: header
}
let response = this.httpClient.post(this.homeUrl + '/admin-signup', obj, options);
response.toPromise().then(data => {
console.log('response: ', data);
//TODO: handle HTTP errors
}).catch((err) =>{
console.log('error', err);
});
Hope it solve your problem.
I'm not familiar with ionic
but I'm guessing its a cors issue
can you try use cors?
const cors = require('cors');
app.use(cors());
I am trying to do an HTTP GET request to an external API with NodeJS (using Express), but I am not getting any data back. My code is the nextone:
import * as http from "http";
const options = {
host: "EXAMPLE.COM",
path: "/MY/PATH",
headers: {
"Content-Type": "application/json",
"Authorization": "Basic XXXXXXXXXXXXXXXXXX"
}
};
const req = http.get(options, function(res) {
console.log("statusCode: " + res.statusCode);
res.on("data", function (chunk) {
console.log("BODY: " + chunk);
});
});
But the response I get is:
statusCode : 302 and BODY is empty.
The external API works properly (I have tried doing a http GET Request with INSOMNIA and returns data)
The request I am doing NEEDS an Authorization Token
What am I doing wrong? or what can I do to get the data back?
Cheers
You are just throwing data to console.log and not responding to request.
You did not mention if what http server you are using with node. In case you are using express.js (most common one) you should have something like:
const express = require("express");
const app = express();
const port = 3003;
const http = require("http");
// your webserver url localhost:3003/fetch-something
app.get("/fetch-something", (req, res) => {
const options = {
host: "EXAMPLE.COM",
path: "/MY/PATH",
headers: {
"Content-Type": "application/json",
Authorization: "Basic XXXXXXXXXXXXXXXXXX"
}
};
const httpReq = http.get(options, function(httpRes) {
//output status code to your console
console.log("statusCode: " + httpRes.statusCode);
httpRes.on("data", function(chunk) {
// still nothing happens on client - this will also just print to server console
console.log("data", chunk);
// return some data for requested route
return res.send(chunk);
});
});
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));