I have followed this Tutorial for creating a restful Api with Nodejs and Mongo. It works fine except a few problems.
My Player model is
var player = new mongoose.Schema({
name: String,
email: String,
score: String
});
When I try to post data through Postman extension on Chrome/Firefox, I cannot post the data. The response is the following
"__v":0,"_id":"54fed7cf5dde9b1c1e90ed6c"}
However, if I make the request through terminal with
curl -XPOST http://localhost:3000/players -d 'name=ronaldo&email=ronaldo#com&score=232'
it works fine.
In addition to this, when try to post or get an Ajax request, I keep getting CORS error even though I added
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
I also tried to use cors middleware but no luck.
The server is running at http://92.222.36.106:3000/players for temporarily testing purposes. Feel free to use Postman to post data.
It seems to be working fine. In Postman check that:
Content-Type is set to application/json
body type is set raw and JSON is selected.
Here's some sample data:
{
"name": "Mariano Rajoy",
"email": "sobres.manila#pp.com",
"score": 0
}
If that doesn't work, here's a working example. Save this to a .json file and import it as a collection:
{"id":"d7fd0131-247a-08c0-4c89-5b46712201b8","name":"Players api","timestamp":1425989704352,"requests":[{"collectionId":"d7fd0131-247a-08c0-4c89-5b46712201b8","id":"2c301d19-62e6-6ad5-40bb-0fbec97305be","name":"http://92.222.36.106:3000/players/","description":"","url":"http://92.222.36.106:3000/players/","method":"POST","headers":"Content-Type: application/json\n","data":"{\n \"name\": \"Mariano Rajoy\",\n \"email\": \"sobres.manila#pp.com\",\n \"score\": 0\n}\n","dataMode":"raw","timestamp":0,"responses":[],"version":2}]}
(In your code 'Access-Control-Allow-Origin' is set to 'http://localhost:8888', but i'm assuming you already set it to '*' since i'm using your api with Postman)
EDIT:
Tried with a regular ajax request and it didn't work. Apparently you still have"Access-Control-Allow-Origin" set to "http://localhost:8888" instead of "*" in your code and Postman / Chrome apps can bypass Cross Origin, didn't know that..
set your cross origin request headers properly ,above you are accessing the request from "http://localhost:8888"(set it your domain) .it allows that domain only.Make sure your domain is properly set it or not .
It allows request from any origin
res.setHeader('Access-Control-Allow-Origin', '*');
It allows request from only "http://localhost:8888"
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
Related
I'm working on a small ToDo app where I've Angular as front-end and Node.js/Express/Mongo as middleware/backend.
While I submit Login in my Login form, it hits the login API, however it returns one strange output in the console saying
OPTIONS http://localhost:3000/api/v1/users/login/ 0 {}
(see screenshot below) which doesn't allow me to get the dashboard even after successful login.
I've enabled CORS through installing the cors NPM module. and I've checked RESTFul services in Postman, and all are working fine.
[Updated] This is how I've enabled the CORS in my express.js's app.js file.
let cors = require('cors');
app.use(cors());
app.options('*', cors());
before a CORS request is sent to the server, clients will always send this "OPTIONS" request as a "preflight request", soliciting supported methods from the server.
This request being blocked may be an indicator of a wrong CORS configuration or an explicit block of all "OPTIONS" requests from the server. (CORS needs to be configured on the server as well).
More information can be found here
It seems that this is a known nodejs issue that is still open.
Based on the open github, seems that the best recommendation is to try something like this:
you need to allow both:
// Http.OPTIONS method for request that is hitting " apiUrl =https://127.0.0.1:3000/login".
// Allow CORS like below:
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'content-type');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
Another great idea is to use the angular proxy settings for local development so that you will not need to add CORS for localhost at all.
Very good guidance in this SO answer here on setting up a proxy for angular If this work, then you can make 100% sure that it is indeed a CORS problem.
To handle CORS in express you dont need to add any dependency.
Notice that http://localhost:4200 is you angular app.
This worked for me:
//Add here whatever route you are using for the api.
app.use('/api', (req, res, next) => {
//Where http://localhost:4200 is the angular app
res.header('Access-Control-Allow-Origin', 'http://localhost:4200'),
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
next();
})
Note:
This goes after the place where you import the routes and before where you use them. kind of like:
const apiRouter = require('./app_api/routes/api_routes');
//The code i posted here
app.use('/api', apiRouter);
I have my application running locally on my computer and it is trying to connect to my remote nodeJS/Express server. I have set the headers in my remote server.
Main question: How do I allow my remote server to accept requests coming from my localhost with parameters? People have told me that my request will not work because the requested URL and the server URL do not share the same domain. The request is coming from my localhost and it is trying to access my remote node/express server. This transaction works when I remove the params in the request but does NOT work when I have the params.
This is how I set headers in my remote server to accept all requests:
app.use(function (req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "http://localhost:9000");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
if(res.headersSent) {
console.log("Headers sent");
}
else {
console.log("Headers not sent");
}
next();
});
Also, the res.headersSent keeps evaluating to false even though I can see the headers set in my Google network tab. Why is this value returning false?
This is how I am making my GET request to my server from my localhost:
var req = $http({
url: 'https://20161128t135355-dot-jarvis-hd-live-2.appspot-preview.com/read-message',
method: 'GET',
cache: false,
params: {last_updated: last_updated_time}
});
This post was not helpful How to enable cross-origin resource sharing (CORS) in the express.js framework on node.js
I think the params is causing the error, because it works fine when I take it out. I get this error:
XMLHttpRequest cannot load https://20161128t135355-dot-jarvis-hd-live-2.appspot-preview.com/read-message?last_updated=0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 502.
All the solutions say to add/set the header and as you can see I have done that but my application still gives me the same error when I include params in the request. What should I do differently?
So that means your problem is that your server side code throws an error when you add params to the request. You need to debug that. The CORS stuff is almost certainly irrelevant.
This issue is not a CORS issue, it has something to do with my params request. To fix this, I had to configure body-parser like so:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
This helps when sending JSON data to the client from the server or vice versa. You can find more information here: http://junerockwell.com/difference-parameters-query-strings-express-js/
I am trying to integrate facebook login for my app in nodejs, angularjs using passport-facebook module.
I can intergrate facebook authentication without angularjs, but when i use angular http.get('/auth/facebook')
i am getting below error
XMLHttpRequest cannot load https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http%…%2Flocalhost%3A1439%2Fauth%2Ffacebook%2Fcallback&client_id=xxxxxxxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:1439' is therefore not allowed access.
app.js:153 err
Below is my angular code
var headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type': 'text/html'
};
$scope.fblogin=function(){
// $window.location.href='/auth/facebook';
$http({
url:'/auth/facebook',
method:'GET',
headers: headers
}).success(function(data){
console.log(data);
}).error(function(){
console.log('err');
});
};
pp.config(['$routeProvider','$httpProvider',
function($routeProvider,$httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.headers.common = 'Content-Type: application/json';
delete $httpProvider.defaults.headers.common['X-Requested-With'];
NodeJs
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
**Note:**I have tried changing multiple header changes for $http.get()
Solution:
The link https://www.facebook.com/dialog/oauth?... is not designed for calling it as ajax because it must REDIRECT user to facebook login page (so when you call it by ajax then redirect is impossible).
Instead of make ajax request just prepare in html proper element:
<a href="https://www.facebook.com/dialog/oauth?..." > ... </>
This works :)
This is what I have done to avoid Angular to call facebook auth dialogue API as AJAX request.
Use 'window.location="http://localhost:3000/auth/facebook"'; in your Angular Controller Function from where you send the request to your Express Server which contains passport.authenticate stuff.
Example:
$scope.authFacebook = function() { window.location="http://localhost:3000/facebook" }
You are attempting to make an ajax call to a URL and the browser is rejecting that ajax request because of cross origin security.
There are several possible reasons for this:
The domain of that URL doesn't allow cross origin requests.
You aren't making the request in a proper way for the cross origin request to succeed.
Your request is not formed properly (either targeted at the right URL or sent with the right options).
FYI, your node.js code where you set the allow-origin headers has absolutely nothing to do with the browser code attempting to send an ajax call to Facebook. That code would allow other people's web sites to make cross origin requests to your node.js server.
One thing that is a bit confusing about what you posted is that the URL of the $http() call you show is not the same URL as you are getting in the error message so I'm wondering if you're looking at the wrong code for the error.
This solution works for me, adding to cors to express app
var cors = require('cors')
var app = express()
app.use(cors())
I am trying to connect my cordova/phonegap application with my node.js server. Problem is, I get this error "XMLHttpRequest cannot load http://127.0.0.1:1234/api/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. The response had HTTP status code 500. " . I tried adding this middleware to my node.js server, entering my phonegap domain, then, just for testing purpouses of course, I figured I will allow ALL domains for CORS, still no luck. This is what I used on my node.js server:
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
And I am doing a pretty simple AJAX request from my phonegap application, which I think is pretty much correct. I am getting this error on my phonegap app and on the node.js server console I get an error from one of the controllers, saying can't see property X of undefined, which undefined is my req.body. Here is the request:
var serverURL = 'http://127.0.0.1:1234';
var body = {
userId : '123A',
comment: {
from: '123B',
content: 'I am a new generation of 123! :)'
}
};
var bodyToString = JSON.stringify(body);
$.ajax({url: serverURL + "/api/plates", dataType: "json", type: "PUT", data: bodyToString}).done(function (data) {
alert(data);
});
Allowing * origin access on your node server is a bad idea. http://docs.phonegap.com/en/1.9.0/guide_whitelist_index.md.html you can declare all domains to be supported by your app in phonegap itself, using element in cordova.xml. have a look at this Phonegap Cross-domain AJAX POST Request not working on Android
Edit
:
From comment below: if you need to allow access to any origin from chrome just for development purpose there is a plugin https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
Suppose I've authorized in domain boo.com already and have this session:
s:x2GYrvxGgmsfFwx7gDbKXmwB.4BDXLpMaSqD9hgeTkBDx3z4TeczJeC50gnrH5bc+kWU
What I want is to add a script tag to domain foo.com, points to boo.com:
<script src='http://boo.com/blah.js'></script>
In all browsers including Safari and Google Chrome, the script tag sets the cookie value in HTTP headers but it doesn't work in Firefox.
Firefox doesn't set the cookie headers so I get Unauthorized error from server. What is the problem?
UPDATE:
I enabled CORS in server-side but the problem is still exist in Firefox:
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://foo.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'Cookie');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
Here is the solution:
<script src="http://boo.com/blah.js" crossorigin="anonymous"></script>
Read more here:
http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html
I found the problem. Because my Firefox doesn't accept third-party cookie, the script tag and all other http requests from another domain don't share the cookie.