Node/Expressjs 'No Access-Control-Allow-Origin header is present' Twitter API - javascript

I'm using Node with Express with the twit and express-cors modules for a Twitter API app.
I got everything working with jQuery and I'm now trying to get it working with vanilla JS.
I get the console message "XMLHttpRequest cannot load https://api.twitter.com/1.1/search/tweets.jsonq=%23cats&callback=?. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:3000' is therefore not allowed access. The response had HTTP status code 404."
This happens both with and without the callback parameter.
So here is the relevant Node code:
var express = require('express'),
cors = require('express-cors'),
Twit = require('twit'),
path = require('path');
var T = new Twit({
consumer_key: ''
, consumer_secret: ''
, access_token: ''
, access_token_secret: ''
})
var app = express();
app.use(cors({
allowedOrigins: [
'twitter.com'
]
}))
app.get('/api/search/:hashtag', function(req, res){
T.get('search/tweets', { q: '#cats', count: 5 }, function(err, data, response) {
res.jsonp(data); // jsonp or json, neither seem to work
console.log(data)
});
});
app.param('hashtag', function(req, res, next, hashtag){
req.hashtag = hashtag;
next();
});
The AJAX call is as follows:
document.getElementById("submitButton").addEventListener("click", function(){ getCORS(url, success); });
function getCORS(url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = success;
xhr.send();
return xhr;
}
getCORS('https://api.twitter.com/1.1/search/tweets.jsonq=%23cats', function(request){
response = request.currentTarget.response || request.target.responseText;
console.log(response);
});
It was working with the jQuery version without the express-cors module even. What am I missing here?

Looks like you're mounting the cors middleware twice. See if getting rid of the first app.use(cors()) fixes it. Then you can try using curl to test it out. curl -v -H "Origin: https://twitter.com" http://localhost:3000/ replacing the port 3000 with the port you're using.

Related

socket.io, vTiger, and csrf-magic.js. CORS issues

I'm attempting to create and add a socket.io module to my vTiger 7.0 so that I can update fields in real-time to multiple users.
We are have issues with users changing fields that should be locked while our quality control is attempting to check the record. This is causes things to get approved that should not. Node.js with vTiger will be awesome add-on.
The only problem is that vTiger uses csrf-magic.js to create a token that need to be included in the header to allow CORS
I have the middleware setup in my node project to allow my vtiger to make a request
vTiger is on vtiger.example.com
The node server is on node.example.com:3010
//server code node.example.com:3010
const fs = require("fs");
const config = require("./core/config").config();
var options = {
key: fs.readFileSync(config.key),
cert: fs.readFileSync(config.cert),
ca: fs.readFileSync(config.ca),
requestCert: true,
rejectUnauthorized: false,
};
const app = require("express")();
const server = require("https").Server(options, app);
const io = require("socket.io")(server);
// Need to send io to socket module
module.exports = io;
app.use(function (req, res, next) {
var allowedOrigins = [
"https://node.example.com",
"https://vtiger.example.com"
];
var origin = req.headers.origin;
if (allowedOrigins.indexOf(origin) > -1) {
res.setHeader("Access-Control-Allow-Origin", origin);
}
res.header("Access-Control-Allow-Methods", "GET, OPTIONS");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.header("Access-Control-Allow-Credentials", true);
return next();
});
io.sockets.on("connection", require("./sockets/socket.js"));
const qc = require('./models/qc_model');
app.get('/', (req,res) => {
res.json({message: 'No Access'});
})
qc.pullLeadInfo(13622196, 10730, (data) => {
console.log(data.lead.lsloa_ver_by);
});
//Start the server
server.listen(config.port, () => {
console.log("server listening on port: " + config.port);
});
\\client side vtiger.example.com
var socket = io.connect('https://node.example.com:3010');
I get this error
Access to XMLHttpRequest at 'https://node.example.com:3010/socket.io/?EIO=4&transport=polling&t=NmEEc_r' from origin 'https://vtiger.example.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.
csrf-magic.js:41 GET https://node.example.com:3010/socket.io/?EIO=4&transport=polling&t=NmEEc_r net::ERR_FAILED
I cannot find any good documentation dealing with this issue. Any help would be great!
Found the information here
https://github.com/socketio/socket.io/issues/3929
// Server
io.engine.on("headers", (headers) => {
headers["Access-Control-Allow-Private-Network"] = true;
});
// Client
const socket = io({
extraHeaders: {
"Access-Control-Request-Private-Network": true
}
});

Connect node app and server + post image to server

I have a very basic question about a node application, and a question about HTTP requests. It's the first time I create a node app with server, and I just can't seem to get the different components to work together.
This is my server.js
var express = require('express');
var multer = require('multer');
const request = require('request');
const upload = multer({dest: __dirname + '/uploads/images'});
const app = express();
const PORT = 3000;
app.use(express.static('public'));
app.post('/upload', upload.single('photo'), (req, res) => {
if(req.file) {
res.json(req.file);
}
else throw 'error';
});
app.listen(PORT, () => {
console.log('Listening at ' + PORT );
});
Then I have a file app.js with a motion-detection system. Every time motion is detected, a picture is taken. This all works fine.
Then the picture should be sent to the server. This is what I can't figure out.
I created a function toServer() that should post the detected data to the server
const request = require('request');
function toServer(data) {
const formData = {
// Pass data via Buffers
my_buffer: data,
// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
};
request.post({url:'http://localhost:3000/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('Upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
};
Problem 1: when running the server.js on localhost:3000, it doesn't find any of the scripts loaded in index.html nor my app.js.
Problem 2: when running the index.html on live-server, all scripts are found, but i get the error "request is not defined".
I am pretty sure there is some basic node setup thing I'm missing.
The solution for toServer() might be more complicated.
Thanks for your time,
Mustard Shaper
Problem 1:
this could happen because you have not specified to render your index.html.
for example:
res.render('index')
if it's not because of the single quotes in upload.single('photo') try double quotes.
Another possible error could be that you are missing a default display engine setting.
an example: https://www.npmjs.com/package/hbs
Problem 2:
it may be because you are missing the header
var request = require('request');
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'http://localhost',
body: "example"
}, function(error, response, body){
console.log(body);
});
See more at https://expressjs.com/

How to solve CORS issue in swagger-ui-express

I'm getting "Possible cross-origin (CORS) issue?" error for Spec2 when run this swagger-ui-express app:
const express = require('express');
var cors = require('cors');
const app = express();
const swaggerUi = require('swagger-ui-express');
var options = {
explorer: true,
swaggerOptions: {
urls: [
{
url: 'http://petstore.swagger.io/v2/swagger.json',
name: 'Spec1'
},
{
url: 'http://xxx.xxx.xxx.xxx:xxxxx/swagger.json',
name: 'Spec2'
}
]
}
}
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(null, options));
app.listen(8080, () => console.log(`Listening on port 8080!`))
Neither app.use(cors()) nor app.use(swaggerUi.cors()) helps. How can it be fixed?
I am not sure if this is exact problem you are facing, but the following solution has fixed my issue.
I was using a fetch on an endpoint and the error suggested that the received request has an origin (header) of value null.
I have set up a request interceptor to add an origin header on the request. Example
app.get("/docs", swaggerUi.setup(null, {
swaggerOptions: {
requestInterceptor: function(request){
request.headers.Origin = `http://localhost:3000`;
return request;
},
url: `http://localhost:3000/docs/api-doc`
}
}))
check the link which gives the way to overcome the issue. Also, you can install CORS plugin in chrome if you want and try it.

How to use a node.js back-end server to interact with the front-end and a mongolab database?

I am building a website with a simple jquery/html/css front-end and a node.js server back-end. If my front-end has a function to request a user's information from the server like so:
function requestUser(email, password) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://localhost:8888/getUser/" + email + "/" + password, true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log(xmlhttp.responseText);
}
}
xmlhttp.send();
}
and my node server looks like this:
var http = require("http"),
mongojs = require("mongojs"),
fs = require("fs"),
url = require("url");
express = require("express")
var server = http.createServer(requestHandler);
server.listen(8888);
var uri = "mongodb://<dbuser>:<dbpassword>#ds036698.mongolab.com:36698/alirodatabase";
var db = mongojs(uri, ["Papers", "Users"]);
console.log("node server running back end of app");
function requestHandler(request, response) {
//request for user is .../getUser/<username>/<password>
var path = url.parse(request.url).pathname;
var details = path.split('/');
if(details.indexOf("getUser") != -1) {
console.log("recieved request for user");
var user = db.Users.find({"email": details[details.indexOf("getUser") + 1],
"password": details[details.indexOf("getUser") + 2]});
user = user.toArray[0];
response.writeHead(200, {"Content-Type": "text/json"});
response.write(JSON.stringify(user));
}
else {
fs.readFile("./index.html", function(err, file) {
if(err) {
return
}
response.writeHead(200, {"Content-Type": "text/html"});
response.end(file, "utf-8");
});
}
}
why isn't it working? I get a 'mixed content' and/or 'corss-origin' error from firefox when I try to request from the server. How can I have the node server running in the same domain as the rest of the site to avoid these errors?
is really hard to read your code, I understand what you are trying to do, but let me suggest first a better structure easier to read, understand and implement more routes for your server, please check here:
var express = require('express'),
cors = require('cors'),
app = express();
app.use(cors());
app.get('/getUser/:user/:passwd', function(req, res, next) {
// Perform all mongo operations here using req.params.user and req.params.passwd
// and in the callback send a response like the object below
res.json({
msg: 'This is CORS-enabled for all origins!',
user: req.params.user,
passwd: req.params.passwd
});
});
app.listen(8888, function() {
console.log('CORS-enabled web server listening on port 8888');
});
Also the lack of CORS support (https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) as you will need this in your use case for if you are planning to host serve static files consuming this service hosted in a different server, so lets use this module: https://www.npmjs.com/package/cors and it will allow express to process a request from anywhere.

Socket.io No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access

I'm trying to learn nodejs with socket.io and at the moment I'm using this tutorial by GianlucaGuarini. When entering my client.html file I get the following error. I know what it means and that it´s there for preventing Cross browser scripts but I don´t know how to allow my nodejs script to access the client.html file.
XMLHttpRequest cannot load http://localhost:8000/socket.io/?EIO=3&transport=polling&t=1422653081432-10. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Here is a part of my code with socket.
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'database',
port: 3306
}),
POLLING_INTERVAL = 3000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function(err) {
// connected! (unless `err` is set)
console.log(err);
});
// creating the server ( localhost:8000 )
app.listen(8000);
// on server started we can load our client.html page
function handler(req, res) {
res.writeHead(200, {
/// ...
'Access-Control-Allow-Origin' : '*'
});
fs.readFile(__dirname + '/client.html', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(200);
res.end(data);
});
}
Does anyone know how I can solve my problem?
Kind regard / H
First of all - stop use writeHead everywhere. Because it rewrite completely response headers.
If tour write like this:
res.writeHead(200,{"coolHeader":"YesIAm"});
res.writeHead(500);
then node.js will sent response just with status 500 and without header "coolHeader";
If you wanna change Status Code, then use
res.statusCode = ###;
If you wanna add new header use
res.setHeader("key", "value");
And if you wanna rewrite all headers then use writeHeader(...)
Second. Add this code
res.statusCode = 200;
//...
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
instead of your
res.writeHead(200, {
/// ...
'Access-Control-Allow-Origin' : '*'
});
and replace all writeHead(###) with res.statusCode = ###;
Try setting the `Access-Control-Allow-Origin' header on your response object in Node.
response.writeHead(200, {
/// ...
'Access-Control-Allow-Origin' : '*'
});
Looks like you are calling .listen for both the app and the socket.io (I believe that is redundant since you are extending your server with socket.io)
I have a little piece that works fine for me using socket.io 1.x
I like to use https since it kills some issues with firewalls and antiviruses, but this example is rewritten to http.
var http = require('http'),
socketio = require('socket.io'),
options={},
port=8080;
//start http
var app = http.createServer(options, handler),
io = socketio(app, {
log: false,
agent: false,
origins: '*:*'
// 'transports': ['websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']
});
app.listen(port);
console.log('listening on port ' + port);

Categories

Resources