CORS workaround in Angular.js $HTTP POST? - angularjs

Is there a workaround to sending POST request cross-domain via Angular, besides using a proxy? Below request is refused, ie: OPTIONS , net::ERR_CONNECTION_REFUSED It's just form data I want to submit to friend's local server for school project.
$scope.postJSON = function(){
var objJson = angular.toJson($scope.event);
console.log(angular.toJson($scope.event));
delete $http.defaults.headers.common['X-Requested-With'];
$http({
method: 'POST',
url: 'http://friendslocalserver.com',
data: objJson
}).success(function() {
console.log("POST Json object worked!");
}).error(function(){
console.log("POST Json object failed!");
});
}

You don't need to configure AngularJS for CORS. Your friend's server needs to support CORS requests and probably whitelist your domain. This depends heavily on the HTTP server used.

Related

Unable to get $http.post request data in Node.js res.body

I am using Angular 1.3 and node.js 0.12.2 for a project. I am hitting the node.js api using
$http.post("url", request_data){}
And on server side using this:
console.log(req.body)
But everytime the api gets called, it gets empty object {} for request_data , Unable to get what the problem is. I have used body_parser like this:
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
Have also tried adding content-type header in angular $http as:
headers : {'Content-Type': 'applicatio n/x-www-form-urlencoded'}
But not getting request data.
EDIT:
Node.js code :
router.post('/url',function(req,res){
console.log(req.body)
})
Note: Developer Tool's network tab showing the data, I am sending, in request header correctly, but node.js server not receiving in req.body.
In POSTman getting data is correctly in response.
some ideas :
Maybe an URL error ? Make sure you aren't using a prefix like app.use('/api', router);
Look at the Content-Type :
application/x-www-form-urlencoded --> 'var1="SomeValue"&var2='+SomeVariable
application/json;charset=UTF-8 --> {var1:"SomeValue", var2:SomeVariable}
You could use $http more explicitly :
$http({
url: '...',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'var1="SomeValue"&var2='+SomeVariable
});
My best guess is that your angular $http request URL is pointing to a bad end-point.
Angularjs
// data to post nodejs server
var _data = {
'message': 'Can I help you?'
};
// angularjs $http post request
$http.post('/api/url', _data).then(function(respond){
// if success
console.log(respond);
}, function(error){
// if an error
console.error(error);
});
Nodejs
// router function
function something(req, res) {
// console.log the request body
console.log(req.body);
// respond JSON object
var _respond = {
'status': 200
};
// expressjs respond a JSON with status code 200
res.status(200).json(_respond);
}
// register route URL
router.post('/api/url', something);
Note that the code end point URLs are same : /api/url
Therefore as your code sample in above question, you'r missing a /

Access Control Allow Origin | AngularJS

I was integrating the flickr app into my app.
I am receiving the error below:
XMLHttpRequest cannot load https://api/flickr.com/services/rest?api_key=4cd95b5ad05844319ee958bf96ec0150&format=json&method=flickr.photos.search&nojsoncallback=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sinch12j12.ads.autodesk.com' is therefore not allowed access. The response had HTTP status code 400.
Below is the client side code:
(function() {
'use strict';
angular.module('flickrApp', ['ngMaterial'])
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
.controller('ListController', ['$scope', '$http', function($scope, $http) {
$scope.results = [];
$scope.search = function() {
$http({
method: 'GET',
url: 'https://api/flickr.com/services/rest',
params: {
method: 'flickr.photos.search',
api_key: '4cd95b5ad05844319ee958bf96ec0150',
text: $scope.searchTerm,
format: 'json',
nojsoncallback: 1
}
}).success(function(data) {
$scope.results = data;
}).error(function(error) {
console.log(error);
});
}
}]);
})();
Please let me know how shall it may be resolved ?
You are trying to make AJAX requests to a different server (domain), that does not allow ajax requests from other domains. There are 2 solutions to your problem :
Edit the configurations of the remote server (Allow-Origin header) to allow AJAX requests from other servers. I think this solutions is not feasible in your case, as you are not capable of configuring the flickr server
Create a proxy server component in your server, exposing an API to your application. Thus, you will make the AJAX requests to your API (and since it is the same domain, you will not have a cross-domain request issue), and your server will make the requests to the flickr API and respond in your AJAX call.
You're trying to use AJAX to retrieve some data from a remote server (in this case, the Flickr server). For security reasons, AJAX calls to any file on a remote server is not permitted unless that file has allowed AJAX calls from remote servers. Here, the Flickr file your trying to get doesn't allow AJAX calls from any other servers, that's why you won't be able to access the data in that file.
Thanks and let me know if you have any more problems.

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.

AngularJS POST fails with No 'Access-Control-Allow-Origin' when using data payload object but works using query params like payload

I am facing a weird issue. I am running my angularjs app in nodejs server locally which calls a POST API from my app located on Google App Engine. The API is configured with all CORS headers required as follows:
def post(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers.add_header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
self.response.headers.add_header("Access-Control-Allow-Headers", "X-Requested-With, content-type, accept, myapp-domain")
self.response.headers["Content-Type"] = “application/json; charset=utf-8”
GET requests to the API work without issues.
POST requests to the API work but ONLY when I send the post data as a 'string of params' and NOT when post data is sent as an object which is the right way to do. Eventually I need to be able to upload pictures using this API so the first solution below might not work for me. Please help!
METHOD 1: This works:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = "conversationid=1c34b4f2&userid=67e80bf6&content='Hello champs! - Web App'";
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz",
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
METHOD 2: This fails:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = ({
'conversationid' : '1c34b4f2',
'userid' : '67e80bf6',
'content' : 'Hello champs! - Web App'
});
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz"
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
When I use METHOD 2 it fails with the following error in the console:
XMLHttpRequest cannot load https://myapp-qa.appspot.com/message.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://0.0.0.0:8000' is therefore not allowed access.
Please let me know if you have any solution. Thanks in advance.
The issue is most likely with Angular sending a pre-flight OPTIONS request to check the access headers from the server. I am not sure how OPTIONS requests are handled in your API, but I am betting these headers are not being added. I suggest installing Fiddler to monitor the actual requests to see what is going on with the headers. You may only be adding them to your POST responses.
See this answer for details on why METHOD 1 may work in this scenario, while METHOD 2 does not.
Here are some more details about pre-flight requests.

Web API loads via URL but get Error 404 from Angular script

I have a WebAPI method here:
http://localhost:50463/api/movies
and when accessing it from a browser it loads perfectly.
In my project (the same project as where Web API resides) when calling the method from AngularJS I get an error 500:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
When I click the link in the error it loads the data perfectly.
The routing for WebAPI is as follows:
config.Routes.MapHttpRoute("DefaultApiGet", "Api/{controller}",
new {action = "Get"},
new {httpMethod = new HttpMethodConstraint(HttpMethod.Get)}
);
This is the angular call
app.factory('dataFactory', function ($http) {
var factory = {};
factory.data = function (callback) {
$http.get('/api/movies').success(callback);
};
return factory;
});
I added this javascript just to rule-out angular, I get the same:
$.ajax({
url: "/api/movies",
type: 'GET',
//data: "{ 'ID': " + id + "}",
contentType: "application/json; charset=utf-8",
success: function(data) {
alert(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
});
Any idea what I have done wrong?
I assume your Web API and AngularJS app are running on a different port. In this case you are running in a Same-Origin-Policy issue.
Ensure your Web API is responding with HTTP CORS headers e.g.:
Access-Control-Allow-Origin: http://<angular_domain>:<angular_port>
or
Access-Control-Allow-Origin: *
Doesn't look like a CORS issue to me as you are using a relative URL in your $.ajax() request.
Did you try $.getJSON("/api/movies").then(successHandler, faulureHandler)
Not sure of that will help but for one you are sending a contentType header with a GET request which contains no content. There should be an Accept header instead, but WebAPI should be fine without one.
I would also remove the constrains from the routing and revert back to the default route mapping to see if the problem is there.
config.Routes.MapHttpRoute("DefaultApi",
"api/{controller}/{id}",
new {id = RouteParameter.Optional});

Resources