Send XML Request to a server on an outside domain using angularJS

3,009 views
Skip to first unread message

Anubha Garg

unread,
Aug 20, 2014, 3:48:13 PM8/20/14
to ang...@googlegroups.com
Hi,

I am working on an application which needs to send a 'post' request to a server residing on a separate domain. The request and response data are of type XML. I tried using $http and $http.post methods, but it did not work. I get the following error message:

"XMLHttpRequest cannot load "myUrl". No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:1337' is therefore not allowed access. "

After searching online and asking on the chatroom I came to know that these methods can only be used for JSON data.

My Code currently looks like this :

App.js:
-------------

angular.module('SmartZone', SmartZone.ModuleRegistry).
config(function ($provide, $stateProvider, $urlRouterProvider, $httpProvider) {
/*------------------Other Code ----------------------------------------*/
        //Allow http requests outside the domain
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
})


Widget Controller:
----------------------------

controller('Controller', ['$scope', 'dataManager', '$http', function($scope, dataManager, $http){
/*------------------------------- Other Code -------------------------------------*/
        $scope.url = "myUrl";
        $scope.data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="********************************************">'+
            '<soapenv:Header>'+
            '<sch:SmartNoteAuthentication>'+
            '<sch:User>***********</sch:User>'+
            '<sch:Password>*********</sch:Password>'+
            '</sch:SmartNoteAuthentication>'+
            '</soapenv:Header>'+
            '<soapenv:Body>'+
            '<sch:SmartNoteRequest>'+
            '<sch:PatientNote>Headache & neck pain</sch:PatientNote>'+
            '<sch:PatientDemographicInfo>'+
            '<sch:AgeRange><sch:Code>8</sch:Code><sch:Name>Adult</sch:Name></sch:AgeRange>'+
            '<sch:Gender><sch:Code>m</sch:Code><sch:Name>Male</sch:Name></sch:Gender>'+
            '</sch:PatientDemographicInfo>'+
            '<sch:ProcessType>NLP_And_DiffDiag</sch:ProcessType>'+
            '</sch:SmartNoteRequest>'+
            '</soapenv:Body>'+
            '</soapenv:Envelope>';
        alert($scope.url);
        alert($scope.data);
        $scope.config = "{ 'Content-Type': 'text/xml', 'Access-Control-Allow-Origin' : '*', 'Access-Control-Allow-Methods' : 'GET,POST', 'Access-Control-Allow-Headers' : 'Content-Type' }";
        alert($scope.config);
        $http({
            method: 'POST',
            url: $scope.url,
            data: $scope.data,
            headers: $scope.config
        })
            .success(function(data) {
                alert("http request was successful");
                alert("data is : "+data);
                alert("status is : "+status);
            })
            .error(function(data, status) {
                alert("http request failed");
                alert("data is : "+data);
                alert("status is : "+status);
            });
    }])


 Can you tell me how I can achieve the above task? Kindly let me know if I need to provide any further information to help resolve this.

Thanks,
Anubha Garg

Eric Eslinger

unread,
Aug 20, 2014, 4:10:48 PM8/20/14
to ang...@googlegroups.com
This is actually a problem on the server side. If the API is designed to be used by applications not hosted on the server, it needs to be configured with CORS (cross-origin resource sharing) headers to allow this.

The actual setup for doing that varies by server, but it's not too hard, provided you can convince the server admin to do this.

e



--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Anubha Garg

unread,
Aug 20, 2014, 5:32:03 PM8/20/14
to ang...@googlegroups.com
Hi Eric,

This same XmlHttpRequest works correctly when I code with regular JavaScript. Here is the code that works :

var xmlhttp = new XMLHttpRequest(true, true);
xmlhttp.open("POST", "*************************", true);
var sr ='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="*****************">'+
  '<soapenv:Header>'+
 '<sch:SmartNoteAuthentication>'+
'<sch:User>************</sch:User>'+
'<sch:Password>***********</sch:Password>'+
 '</sch:SmartNoteAuthentication>'+
  '</soapenv:Header>'+
  '<soapenv:Body>'+
 '<sch:SmartNoteRequest>'+
'<sch:PatientNote>Note</sch:PatientNote>';
sr+=this.xmlPatientDemographicInfo(requestData);
sr+='<sch:ProcessType>NLP_And_DiffDiag</sch:ProcessType>'+
 '</sch:SmartNoteRequest>'+
  '</soapenv:Body>'+
'</soapenv:Envelope>';
xmlhttp.setRequestHeader('Content-Type', "text/xml");
xmlhttp.onreadystatechange = function(e){
try{
if(xmlhttp.readyState == 4){
if(xmlhttp.status == 200){
self.logTime("received full API response");
}else{

}
}
}catch(e){

}
};
xmlhttp.send(sr);

It does not work when I make the same request in AngularJS using the code mentioned below. Am I missing some header content because of which the server is not allowing access?

Eric Eslinger

unread,
Aug 20, 2014, 5:42:20 PM8/20/14
to ang...@googlegroups.com
Hmm, don't know about that, maybe someone else on the list can diagnose it. Specifically, I'm a fairly new arrival to the client-side world (long time db person), and I've only ever done XHRs via angular's $http methods. I had to update my node.js backend API server to include CORS headers on responses to api requests.

e

Sander Elias

unread,
Aug 20, 2014, 11:33:27 PM8/20/14
to ang...@googlegroups.com

Hi Anubha,

AngularJS is a bit more strict as plain js for security reasons. In some cases that’s a bit of a PITA as you noticed!
However, as your code is using angular, but still IS js, you can use plain JS to do the fetching.
create a service that does the request, and wrap it in a promise, something like this:

    angular.module('goFetch',[])
       .service('goSoap',[
        '$q',
        function ($q) {
            this.get = function (parameters) {
                var defer = $q.defer();
                var xmlhttp = {} // do your normal xmlhttprequest setup here!

                xmlhttp.onreadystatechange = function(e){
                    try{
                        if(xmlhttp.readyState == 4){
                            if(xmlhttp.status == 200
){
                                defer.resolve('received full API response')
                            }else{
                                defer.resolve('oops')
                            }
                        }
                    }catch(e){
                        defer.reject('HOLY...');
                    }
                };
                return defer.promise;
            }
        }]);

After you injected this service into your controller, you can use it like this goSoap.get(paraemters).then(...).catch(...)

Does this help you?

Regards
Sander

Anubha Garg

unread,
Aug 21, 2014, 4:38:58 PM8/21/14
to ang...@googlegroups.com
Hi Sander,

I was able to fix this. My headers were getting sent in as string variable instead of JSON object which was causing the header to be wrong. This change fixed it and I was able to make the call.

Thanks for your time,

Anubha Garg

rohit chauda

unread,
Jan 7, 2015, 7:03:33 AM1/7/15
to ang...@googlegroups.com
Dear Anubha,

I am also facing exactly same issue, Can you please share your code changes to avoid that issue.

Thanks in advance!

Rohit
Reply all
Reply to author
Forward
0 new messages