I have an app that is built using: PhoneGap + AngularJS (client) --- ExpressJS + MongoDB (server). The app is hosted on Amazon EC2 on an Ubuntu machine. The app was working totally fine, till...
On the EC2 machine I did a:
sudo apt-get update
After I did this, I started getting the Cross Origin sharing error in my app (looking at the console in Chrome). In my AngularJS app, I have code like so that was throwing the error:
$http.get('http://amazon.ec2.foo/offers').success(function(data) { });
The error was:
XMLHttprequest doesn’t allow Cross-Origin Resource Sharing on http://localhost:8000
So, I updated my server app like so:
app.all("/api/*", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS");
return next();
});
This seemed fine at first - I stopped getting the Cross Origin error, and I could see the response from the http request in the console. However, my app would stop responding and seemingly hang immediately after printing the response to the console - I am unable to click on any part of the web page, or open the developer console etc. The only resort is to close the tab and re-open it. Other tabs in Chrome were totally fine.
After debugging this for some more time, I figured that earlier (without those app headers), I was getting a HTTP 200 from the server, but now I'm getting an HTTP 304 (NOT MODIFIED), which it seems that Angular treats as an error.
I found that waiting on the tab for about ~2 minutes results in the web page loading up the data it received from the http request - but the web page stays unresponsive.
I've confirmed a few things to narrow this to AngularJS doing something weird on the HTTP 304:
I'm running this on localhost with the same error - so, it has nothing to do with EC2.
I removed mongodb to just send back some simple data - so, it has nothing to do with Mongo.
I'm running this in Chrome as a simple server - so, I've eliminated PhoneGap to be the issue.
Has anyone seen this before / do you know what the problem may be & how I can solve it?
Thanks!
Angular treats a 304 status code as a failure, to catch the 304 (untested):
var prom = $http.get('http://amazon.ec2.foo/offers')
.catch(function(resp){
if(resp.status !== 304){ $q.reject(resp) }
return resp; // response
})
.catch(function(err){
// handle or throw error
});
// Success responses and 304 responses are now available through the $http promise
prom.then( function(resp){ /* handle 200 and 304 response */ } );
Related
Heroku suggests to use NPM packages to handle forcing SSL for express apps. I've tried about a dozen without success. The only thing I can get to work is shown below but then Google gets mad.
Question: Can someone please tell me a working method as of 2022 to force HTTPS on an express app?
<script>
//This works but Google Console gets angry: Page indexing issues: Page with redirect
var host = "www.URL.com" || "URL.com";
if ((host == window.location.host) && (window.location.protocol != "https:")){
window.location.protocol = "https";
}
</script>
If you set the Strict-Transport-Security header, the browser will remember that this is an HTTPS only site after accessing it over HTTPS for the first time. The browser then substitutes every subsequent request to http://your.server with a request to https://your.server, so it will never again visit your site over HTTP.
To ensure that a first visit over HTTPS happens, add a permanent redirect from HTTP to HTTPS. (I don't think this redirect should upset Google, for example, github.com does it in the same way.)
The following code assumes that Heroku runs the app on both HTTP and HTTPS for you.
app.use(function(req, res, next) {
if (!(req.client instanceof tls.TLSSocket))
return res.redirect(301, "https://your.server");
res.set("Strict-Transport-Security", "max-age=86400");
next();
});
I'm making a post request using axios in reactjs after users login. Here it is:
axios.post('https://localhost:3000/api/login/authentication', {
email: email,
password: password
})
.then(response => {
this.props.history.push('/Main')
})
.catch(error => {
console.log(error)
})
It goes in the error and I log it to the console. This is what I get:
Error: "Network Error"
createErrorhttp://localhost:3000/static/js/0.chunk.js:26742:15 handleErrorhttp://localhost:3000/static/js/0.chunk.js:26293:14
Also in case it's any help, I get this warning before the error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:3000/api/login/authentication. (Reason: CORS request did not succeed)
Can anyone please help me solve this issue? Thanks in advance!
If you're using a front-end application that makes request to a back-end API, you need to include certain headers in the API server if the API server is running on a different port.
For example, if you're serving a ReactJS application with webpack in development mode, webpack acts as a server, sending the reactJS application to the client. Then, making requests to the API server will require that the API server, running on a different port, include Access-Control-Allow-Origin headers in all http responses.
Basically, before generating every response, you need to set 'Access-Control-Allow-Origin' to localhost:<port you visit in the browser>.
In a basic express app, you can paste this in your app.js file, for example:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3001');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});
Note: If you may need to change http://localhost:3001 to match the port you visit in the browser.
EDIT: OP is not using express, but is using Webpack. The question is: What is an express-agnostic solution?
Answer: The solution is still the same: regardless of what API server you are using, just set the response headers for every response.
There is another solution that involves Webpack, though:
In the package.json file of your front end code that's being served with webpack, add the following: "proxy" :"http://localhost:<port API server is running on>"
For example, is webpack is serving your front end app to localhost:3000 and your api server is running on localhost:3001, then the proxy in package.json would be:
"proxy":"http://localhost:3001"
You can add the CORS header in webpack dev server config as follows:
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
},
This will add these two headers in your response. Hence solve your problem. However, when your services run on a different server other than your local machine, these headers need to be added in server response.
The very first thing that i am figuring out in your code is that you are using 'https' but it should be only 'http'to make request, because local host uses http.
2)This might be due to cors, Before making any requests , the browser sends a pre-flight request to the API server to know that "This website has been allowed to access your resources or not", so using cors and specifying origin which can access API resources will solve this problem.
I've created an Ionic app which calls an API to post the user's current location.
The request works as follows:
POST: http://mywebsite.com/api/Patients/AddLocation/17
with body:
{
"Latitude": 51.3753786,
"Longitude": -0.0833691
}
However, the following code in my Ionic app does work:
$http.post('http://mywebsite.com/api/Patients/AddLocation/' + $scope.id, data)
.success(function () {
console.log('Updated location');
})
.error(function (error) {
console.log('Error updating location');
console.log("Error: " + error);
});
In which 'data' is the same as the body above.
Any ideas why this isn't working?
UPDATE:
Here's a couple of screenshots of the network request:
Network request available at imgur RWNDF.png
Postman request
It happens if you have not enabled cors in your server.
enable cors in you server.
even if you dont enable cors,
get method will work peerfectly if you have enabled cors using any extension in chrome.
It's because of CORS. Enable cros from the server end and the a header will be set in HTTP Access-Control-Allow-Origin: * .
If your server app is an expressjs app, use below code to enable CORS
var cors = require('cors');
.....
app.use(cors());
Else use chrome extension Allow Cross Origin Request
This should solve the problem
After comparing this to a sister app which uses the same API and works, the only difference I could see was that a few of the plugins were different.
To remedy this I deleted the plugins folder and the platforms folder, re-added android and just the plugins I need, it now works. I guess it's maybe some bug I created by using the wrong mixture of plugins.
A very unsatisfying answer, but all requests work now!
I'm trying to make a simple Angular "$http.post" request to a basic registration REST API, but when I check the network tab (developer tools) in Firefox, the POST request is missing.
$http.post('http://example.com/api/user/userregistration', $scope.userInfo).then(function successCallback(response){
console.log(response.data.object, status);
$scope.processing = false;
$scope.processed = true;
},function errorCallback(response){
console.log(response.config, response.data);
});
I do see a HTTP OPTIONS pre-flight request with 200 OK response, but no subsequent POST request seems to work.
I also tried making a Jquery Ajax POST request to the same API but to no avail.
The same Angular code works perfectly fine in Chrome & Safari (OSX Sierra).
I have attached the screenshot of the OPTIONS request which is returning 200 OK but the subsequent POST request is missing (no errors in console)
Please help troubleshoot the above and suggest if I'm missing something obvious.
Ok found the problem and solved it.
The problem:
The Firefox browser installed in my OSX machine was not showing any error, hence I was unable to troubleshoot.
Checked the same POST request from a Firefox in Windows machine, fortunately saw an error saying:
Cross-origin request blocked. (Reason: invalid token "multipart/form-data" in CORS header "Access-Control-Allow-Headers")
The above error means Firefox does not treat "multipart/form-data" as a valid entry in "Access-Control-Allow-Headers" HTTP response header. (However, Chrome & Safari seem cool about it!)
The Solution:
Removed "multipart/form-data" from the "Access-Control-Allow-Headers" HTTP response header and Voila it worked in Firefox as well!
Mixed Content: The page at 'https://www.example.com/dashboard' was
loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint
'http://api.example.com/inventory/10/'. This request has been blocked;
the content must be served over HTTPS.
We have this Angular web app that runs with Flask on the back-end.
Everything was working fine until we implemented SSL. Afterwards, we keep getting this strange error everywhere.
Now, the $http.get request in my dashboard.js is definitely calling "https://api.example.com/inventory/10" in the code below and yet the error is claiming that we are trying to request "http" instead.
$http.get($rootScope.baseUrl+'/inventory/' + item.id)
where rootScope.baseUrl is "https://api.example.com".
It's really weird because some GET requests ARE going through from our web application to our back-end, but some requests are throwing this weird error.
Here's the header that gets an error in our Network tab of the console in chrome.
Request URL:https://api.example.com/inventory/10 Request Headers
Provisional headers are shown Accept:application/json, text/plain, /
Origin:https://www.example.com
Referer:https://www.example.com/dashboard
It was a weird case that came down to removing a forward slash from the end of a URL fixing everything. Somehow, whenever we made a GET request using $http in Angular like baseurl + inventory.id + "/", it would make a http request but as soon as remove that slash, it would make the https request correctly.
Still so confused
I think the root of the problem is in server redirects. I was able to resolve same issue with SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') setting for Django (its running behind AWS balancer). Here is documentation.