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/
Related
This question already has answers here:
Access from origin 'https://example.com' has been blocked even though I've allowed https://example.com/
(2 answers)
Closed 12 days ago.
I am developing an app with my own sever, i configured my cors with to by client-side host only. Everything seems to be fine i can request data from my database using the GET, but whenever my trying to POST or create, I always have "Response to preflight request doesn't pass access control check:". Please what am I doing wrong? Below is my code
My server-side
const allowedOrigins = [
'http://localhost:3000/'
]
const CorsOptions = {
origin: allowedOrigins,
Credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type'],
optionsSuccessStatus: 204
}
const cors = require('cors')
const CorsOptions = require('./config/CorsOptions')
app.use(cors(CorsOptions))
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
My client-side
const response = await fetch('http://localhost:8000/workout', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type':'application/json'
},
})
const json = await response.json()
if(!response.ok){
errors(json.message)
}
if(response.ok){
reset(data)
console.log('New Workout added successfully', json)
}
The error
Access to fetch at 'http://localhost:8000/workout' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The GET request works perfectly with all these setting above, but for some reason the POST or any other request always gives me this error
I havent done anything yet, i would appreciate any help.
If you're using Chrome to debug your application, then that could be why, since Chrome doesn't support making POST requests from localhost. A bug report was made for this, but it was marked as WontFix, so it's likely not going to change any time soon.
This extension circumvents the issue by setting the Access-Control-Allow-Origin header to *, along with some other stuff.
You may also want to consider this npm package, since you're already using Express.
Hope this helps!
Most likely a permissions issue,
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Configuring CORS headers into server-side code to allow requests from the local host
This header specifies which domains are allowed to make requests to your server.
I have a node web server (express) running on port 6000.
When http://localhost:6000/ is invoked, index.html is served to the client which has a script, logic.js that runs:
var xhr = new XMLHttpRequest();
var url = 'http://localhost:4000/endpoint';
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('endpoint');
callback(xhr.responseText);
}
};
xhr.send(JSON.stringify({'key': 'value'}));
There is another express server running on port 4000.
The server sets up an endpoint which simply returns what the request body submitted:
app.route('/segment')
.post(bodyParser.json(), function(req, res) {
res.set('Access-Control-Allow-Origin', '*');
res.send(req.body);
});
When I access http://localhost:6000/, I'm seeing this in the browser console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4100/segment. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
Is there a way to bypass this during prototyping?
Your endpoint probably doesn't serve the OPTIONS HTTP method which is used by browsers to check CORS headers (before they make the real request).
If you need different CORS headers in development and in production, I think the best way is to add a new backend config option with the value for allowed origins and serve them from some global response filter.
You have set xhr.setRequestHeader('Content-type', 'application/json'); so this is a preflighted request (rule of thumb: A Content-Type that is not a valid value for the enctype attribute of an HTML form will trigger a preflighted request).
Your server side code only sets the Access-Control-Allow-Origin header in response to POST requests. You need to write server side code to respond to the preflight OPTIONS request too.
Here are a few ways to solve this problem:
Best: CORS header (requires server changes)
CORS (Cross-Origin Resource Sharing) is a way for the server to say “I will accept your request, even though you came from a different origin.” This requires cooperation from the server – so if you can’t modify the server (e.g. if you’re using an external API), this approach won’t work.
Modify the server to add the header Access-Control-Allow-Origin: * to enable cross-origin requests from anywhere (or specify a domain instead of *). This should solve your problem.
2nd choice: Proxy Server
If you can’t modify the server, you can run your own proxy. And this proxy can return the Access-Control-Allow-Origin header if it’s not at the Same Origin as your page.
Instead of sending API requests to some remote server, you’ll make requests to your proxy, which will forward them to the remote server. Here are a few proxy options.
3rd choice: JSONP (requires server support)
If CORS and the proxy server don’t work for you, JSONP may help. You essentially make a GET request with a callback parameter:
(get) http://api.example.com/endpoint?callback=foo
The server will wrap the JSON reply in a function call to your callback, where you can handle it:
foo({"your": "json", here: true})
There are some downsides, notably that JSONP only supports GET requests and that you still need a cooperative server.
I'm working with my Raspberry Pi.
I have my raspberry Pi, that on the IP: 192.168.X.X/file.json give me a webpage containing data in json. While trying to built a web page that requests in that page with the following code:
$.getJSON('http://192.168.X.x:8080/file.json', function(data) {
//code }
It returns the an error on the browser:
XMLHttpRequest cannot load http://192.168.X.X:8080/file.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
Can you tell me how to fix it?
And where to put the code to fix it?
Your issue is related to Cross-Origin Resource Sharing (CORS): basically, you cannot access a domain via Ajax if it's not allowed on the server side. This is a "security" feature on most modern browsers. You won't encounter this problem using command line such as curl or chrome's Postman extension.
Make sure the domain requesting the data (localhost) is allowed in the Access-Control-Allow-Origin header, as well as the http verb (GET, POST, PUT... or * for every http methods).
Basically, it comes down to add the two following headers to the http://192.168.X.x/ server's response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
If you use node.js with Express, you can do the following :
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
// or res.header("Access-Control-Allow-Origin", "localhost");
res.header("Access-Control-Allow-Headers", "*");
next();
});
You need to configure your web server to set the appropriate CORS response headers.
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