angularjs $http.get not working on mobile browsers - angularjs

I tried to use this code:
var url = "http://www.test.com?param=1&callback=JSON_CALLBACK";
$http.get(url).success(function(data, status, headers, config) {
if (data.success == 1) {
//do somethings
} else {
//notice
}
});
It is working fine with browsers of laptop but on mobile browsers, it is not working.
in .htaccess, i added:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Please help!

The mobile browser and desktop browser works same way for http calls. You can make an error block in your code to see what error is coming from the server. Below piece of code is what I am suggesting.
this._getAll = function (model) {
var deferred = $q.defer();
$http
.get("your-secure-rest-url")
.success(function (data) {
deferred.resolve(data);
})
.error(function (reason) {
deferred.reject(reason);
});
return deferred.promise;
};
As you are allowing Access origin "*" for all domain, there is no problem in client side but you need to check the rest server if it is accessable from all domain or is it restricted to particular domain.

Related

Access-Control-Allow-Origin when sending request to google api

Im trying to send an request in my angularjs application to google API to get the attractions in a radius around an location. But I get this error message in chrome:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
I've tried both json and jsonp but the result is the same. :S
$http.get('https://maps.googleapis.com/maps/api/place/radarsearch/json?location=51.503186,-0.126446&radius=5000&type=museum&key=<MYKEY>')
.then(function(response) {
$scope.dataResult = response.data;
});
$scope.getlocation = function() {
$scope.method = 'GET';
$http({ method: $scope.method, url: "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=51.503186,-0.126446&radius=5000&type=museum&key=<MYKEY>&callback=JSON_CALLBACK" }).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
console.log(data);
}).
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
I dont want to show result on a map, I only want it in list format.
This is CORS issue, from the client-side you can enable cors requests like this.
angular.module('yourapp').config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
The problem with your case is , https://maps.googleapis.com/maps/api/place/radarsearch/json?location=51.503186,-0.126446&radius=5000&type=museum&key=<MYKEY> does not allow your origin to have access to the response. Therefore you are not able read it.
I hope you have a valid key and also while registering you have listed your localhost in the place of domain... as google needs to know these.

Angular REST cannot return simple data

I am trying to get a $http REST GET call working in my Appgyver project working but nothing I do seems to come right, always returns an error.
Please note the angular app will be running on mobile devices eventually and then connect to my remote web service.
I've double checked that my custom API is working and returning data correctly in a number of ways, namely:
hard coded cUrl request running from sh files in terminal - Returns data and correct 200 code
Tested the API end points in both POSTMAN and Firefox's SOA client.
Putting in my test end point of http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term returns data as below:
[{"tid":"1","vid":"2","name":"ACME Ltd.","description":"","format":"filtered_html","weight":"0","parent":"0","uri":"http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term/1"},{"tid":"2","vid":"2","name":"ABC Films LTD","description":"","format":"filtered_html","weight":"0","parent":"0","uri":"http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term/2"}]
Even a simple CSRF Token request gives me errors.
Could someone possibly point out where I am going wrong here, the Appgyver site is badly documented and I have tried the Angular RESTful sample which my code below is based upon from https://docs.angularjs.org/api/ng/service/$http and https://docs.angularjs.org/api/ng/service/$http#setting-http-headers
Please note the code below is basically Angular.js using Javascript syntax (as opposed to Coffeescript), logging output follows the code
angular
.module('main')
.controller('LoginController', function($scope, supersonic, $http) {
$scope.navbarTitle = "Settings";
$scope.stoken = "Response goes here";
$scope.processLogin = function(){
var csrfToken;
steroids.logger.log("START CALL: processLogin");
// $form_login_email_address = $scope.login_email;
// $form_login_password = $scope.login_password;
$local_get = "http://somesite.com/quote-and-buy-performance/services/session/token";
$hal_get_taxterm_index = "http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term";
// $http.defaults.headers.common.contentType('application/json');
var req = {
method: 'GET',
url: $hal_get_taxterm_index,
headers: {
'Content-Type': 'application/json'
}
}
$http(req)
.success(function(data, status, headers) {
steroids.logger.log("Inside http.get() success");
}).error(function(data, status, headers){
steroids.logger.log("Inside http.get() WITH ERROR");
steroids.logger.log('data: ' + data);
steroids.logger.log('status: ' + status);
}).then(function(data, status, headers){
steroids.logger.log("Inside http.get() then");
});
steroids.logger.log("END CALL: processLogin");
}
});
Logging output from calls to steroids.logger.log
View Time Level Message
main#login 16:01:55.219 info "Inside http.get() WITH ERROR"
main#login 16:01:55.219 info "data: null"
main#login 16:01:55.219 info "status: 0"
main#login 16:01:55.64 info "END CALL: processLogin"
main#login 16:01:55.64 info "START CALL: processLogin"
Here's what I would do:
Separate out your http call into a service. This is a pretty standard way to modularize your code in angular:
angular.module('main').factory("SomeService", function($http) {
return {
get: function() {
$http({
url: "http://somesite.com/quote-and-buy-performance/druidapi/taxonomy_term",
method: "GET",
headers: {
"Content-Type": "application/json"
}
}).success(function(data, status, headers, config) {
console.log("Success!");
console.log(data);
}).error(function(data, status, headers, config) {
console.log("Error!");
console.log(status);
console.log(data);
});
}
}
})
Then to use this in your controller, just include it in your controller declaration and call get like you would a normal method:
angular.module('main').controller('LoginController', function($scope, supersonic, SomeService) {
$scope.navbarTitle = "Settings";
$scope.stoken = "Response goes here";
$scope.processLogin = function(){
var csrfToken;
steroids.logger.log("START CALL: processLogin");
SomeService.get();
steroids.logger.log("END CALL: processLogin");
}
})
Do this and then comment back with your results and we can work from there.
If your angular's app is within a certain domain, then HTTP request must be made within the same domain.
In your case, you are trying a cross domain request (a request on another domain). You must then make a cross domain request.
You can see this question.
The author uses $http.jsonp() to send cross domain requests. There migth be another way to do it.

CORS issue with node rest api and angularJS app on 2 ports

I have the classical CORS issue with my angularJS app (on localhost:9000) trying to catch my node server (on localhost:9001)
Here my rest api (app.js) code :
var cors = require('cors');
app.use(cors());
app.options('*', cors());
app.all('/*', function(req, res, next) {
// CORS headers
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
if (req.method == 'OPTIONS') {
res.status(200);
res.write("Allow: GET,PUT,POST,DELETE,OPTIONS");
res.end();
} else {
next();
}
});
As you can see, i've tried those solutions in vain :
CORS in Node.js and AngularJS
Cors issue when rest api application server(express) and Angulars js application running on different port
And here's the simple $http call in webapp :
var req = {
method: 'GET',
url: 'localhost:9001/memories'
};
$http(req).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
reutrnStatus.success = true;
reutrnStatus.msg = status;
memories = data;
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
reutrnStatus.success = false;
reutrnStatus.msg = status;
});
I tried some solutions in webapp too (in app.js) :
// Enable AngularJS to send its requests with the appropriate CORS headers
// globally for the whole app:
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
/**
* Just setting useXDomain to true is not enough. AJAX request are also
* send with the X-Requested-With header, which indicate them as being
* AJAX. Removing the header is necessary, so the server is not
* rejecting the incoming request.
**/
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
But i'm close to give up because it's still not working... That's giving me this same error :
XMLHttpRequest cannot load localhost:9001/memories. Cross origin
requests are only supported for protocol schemes: http, data, chrome,
chrome-extension, https, chrome-extension-resource.
And just to be fully clear, i followed that tutorial for the rest api :
https://blog.jixee.me/how-to-write-an-api-in-one-week-part-2/
You are making a request to an unknown protocol.
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
You need to change this:
method: 'GET',
url: 'localhost:9001/memories'
};
...to this:
method: 'GET',
url: 'http://localhost:9001/memories'
};
Alternatively, you could set it to //localhost:9001/memories and the browser will use the current protocol which is useful if you're serving resources over both http and https.
Although unrelated, your callbacks have typos in the variable names.

Requesting data to Sharepoint 2013 using rest api service to integrate with angular app

I am learning sharepoint 2013 for a required incoming project. I has never worked on .net or any other ms technology so i would appreciate if the answers are dumb proof.
I have a server that is running sharepoint 2013 and iis v8.0
Currently i am having some issues, but the main one is that i am trying to access the api service from an angular application. I setted the mapping for intranet to the ip of the server and i can access the api through to the web browser.
I also setted the http response headers to "Access-Control-Allow-Origin" : * in iis. However when i try to access the api using the angular $http object i am getting a message that says XMLHttpRequest cannot load http://x.x.x.x/_api/web. 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 401.
The idea is that the angular application is totally independant of sharepoint and any .net technology. All i want to do is use the rest api to get/edit data.
The request i am making looks like this:
angular.module('angYeoman2App')
.factory('SharePointJSOMFactory', function SharePointJSOMFactory($http, $q) {
var deffered = $q.defer();
var data = [];
var myService = {};
SharePointJSOMFactory.getTasksRESTAppWeb = function() {
var restQueryUrl = "http://x.x.x.x/_api/web";
$http({
headers: { 'Accept': 'application/json; odata=verbose' },
method: 'GET',
url: restQueryUrl
})
.success(function(data, status, headers, config){
console.log(data);
deffered.resolve();
})
.error(function(data, status, headers, config){
console.log('error', data)
deffered.resolve();
});
return deffered.promise;
};
SharePointJSOMFactory.data = function() {
return data;
};
return SharePointJSOMFactory;
});
Any idea what i am doing wrong? I has read that i need to add <% Response.AddHeader("Access-Control-Allow-Origin", "*") %> somewhere, but i don't have any idea to what file.
I also have another problem (not so relevant at this point): When i try to access to a subsite using the ip address it seems it is applying the theme of the parent and it doesn't load the content of the subsite. Any idea why?
Any help is welcome. Tks for your time, have a nice day.

Angular JS Custom Headers on GET Turns to Options

So, this has been a huge struggle for us.
We have a web API .net MVC4 back-end. We are using angular for client-side. We have a page that has some JSON that we receive data from. When we make a GET to this page we receive data. As soon as we add custom headers to the call the GET turns into OPTIONS and we get a 200, with no response. We are doing a couple things like creating a BASE64 code on "login" storing it as a cookie and trying to add that to the GET headers. the thing is we have stripped out all of the unnecessary code and we are still at the same problem. Even with authorization turned off for the data. Here is the GET code:
myApp.factory("projectDataService", function ($http, $location, $cookieStore) {
var token = "";
token = $cookieStore.get('token');
return {
getProject: function (successcb) {
$http({ method: "GET", url: "http://dev.projnik.com/api/project", headers: { 'Authorization': 'Basic ' + token } }).
success(function (data, status, headers, config) {
successcb(data);
}).
error(function (data, status, headers, config) {
console.log(data, status, headers, config);
});
},
save: function (project) {
$http({ method: "POST", url: "http://dev.projnik.com/api/project", data: $.param(project) }).
success(function (data, status) {
if (status == '201') {
$location.path('/all');
}
})
}
};
});
And the app.js:
var myApp = angular.module('Project', ['ngResource', 'ngCookies']);
myApp.config(function($routeProvider){
$routeProvider.
when('/new', {templateUrl:'templates/new.html', controller:'EditProjectController'}).
when('/mobile', {templateUrl:'templates/mobile.html', controller:'ProjectController'}).
when('/it', {templateUrl:'templates/it.html', controller:'ProjectController'}).
when('/writing', {templateUrl:'templates/writing.html', controller:'ProjectController'}).
when('/all', { templateUrl: 'templates/all.html' }).
when('/cookie', { templateUrl: 'partials/cookiecontrollerhtml.html' }).
when('/login', { templateUrl: 'partials/_login.html' }).
otherwise({ redirectTo: '/all' });
});
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
Again, without adding headers attribute to the call, everything works (obviously we get a 401 with Authorization turned on in the API). We are willing to pay for an answer at this point.
We are exposing our actual domains here, and that is fine. If someone goes to www.projnik.com and clicks the login link on the top and enter shane, password for username,password they would receive the cookie and it routes the user back to the #/all page where they would GET the data, though it doesn't work.
PS: I have tried to ad withCredentials = true; to the call and I get the same result.
If you are accessing API in dev.projnik.com from a web page in www.projnik.com, in a browser like Chrome, CORS comes into play. If you make a GET without any custom headers, it is a simple CORS request and I assume you have settings in web.config that sends Access-Control-Allow-Origin header and that makes it work. Once you add a custom header, it is no longer a simple CORS and it becomes pre-flighted CORS with browser making an OPTIONS request. The response to this OPTIONS request must send the correct CORS headers for the browser to make the subsequent GET. To enable CORS, check this out. BTW, in IIS there is a default handler that answers OPTIONS call that you might need to remove for the message handler in Web API to respond to OPTIONS.
I am working with Shane on this - the block of code on the server is:
public void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
I believe this takes care of the situation. But the problem is still there.

Resources