2

This issue may not be a new problem for many newbie. I am one among them and I have to handle this issue on client side. So, please don't mark this issue as duplicate.

I have my website client code deployed in a server and this website calls a webservice deployed in some other different server. (Please note: I don't have this webservice code access).

My AJAX code to retrieve data:

$.ajax({
        type: 'GET',
        url: 'http://webservice_url',
        success: function (data) {
             //success
        },
        failure: function(error){
            //error
        }
    });

On accessing this webservice through AJAX, I receive:

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

Browser console log:

  • I can view my webservice's response successfully in browser console (under 'Network' tab -> 'response' tab of my webservice). However, retrieving the above error.

On reviewing many previous posts, I found that by setting response header as:

response.addHeader("Access-Control-Allow-Origin", "*");

will fix this issue.

However, I don't have access to change my webservice code, to add response header. I have to fix this in website.

I have developed this website using ExpressJS and Node. My app code is

var http = require('http');
var routes = require('./routes');
var express = require('express');
var path = require('path');

var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.cookieParser('secret code'));
app.use(express.logger('dev'));
app.use(express.favicon());
app.use(express.methodOverride());
app.use(express.session());
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// Add headers
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');

    // Pass to next layer of middleware
    next();
});

app.get('/', routes.index);

http.createServer(app).listen(3000, function(){
    console.log('Express server started successfully');
});

Adding res.setHeader('Access-Control-Allow-Origin', '*') haven't helped me.

Can anyone guide me.

Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69
  • If you don’t have access to the web service, then you obviously can’t change what response headers it generates – and therefore you can’t use cross-domain AJAX. Go check their docs if they offer other methods of requesting the data, f.e. JSONP. – CBroe Jan 22 '14 at 12:15

1 Answers1

3

This is because cross domain restrictions.

You have added Access-Control-Allow-Headers in your client side code, which is wrong. It should be added in the server-side code i.e. your web service that you are trying to reach.

However, since you don't have access to that web service, you can use the jQuery ajax like shown in this answer

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     jsonp: 'callback',
     jsonpCallback: 'jsonpCallback',
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     },
});

function jsonpCallback(data){
    alert("jsonpCallback");
}

Or, use alternate function explained here

To use jsonp the web service must support the callback parameter, checkout their documentation.

Community
  • 1
  • 1
Salman
  • 9,299
  • 6
  • 40
  • 73
  • Thanks for the quick response. Now I understand the reason why 'Access-Control-Allow-Headers' haven't worked for me. I tried with 'jsonp'. Now I am not retrieving No 'Access-Control-Allow-Origin' error in console! However, still I am not able to receive response data in AJAX success block. On investigating my webservice in browser console (under 'Network' tab -> 'response' tab of my webservice), I receive a valid response. However there is some callback attached in 'Request URL'. As http://MY_WEBSERVICE?callback=jQuery19104137628001626581_1390394111156&_=1390394111157. Can you please guide me –  Jan 22 '14 at 12:44
  • This is how callback in `jsonp` works. You have to pass a callback like I have shown in the updated answer. This callback goes as a querystring parameter and the ws should enclose the response in the callback function. – Salman Jan 22 '14 at 12:51
  • Hi CanMAH, sorry if my question is silly. I am new to JSONP. I used your sample code. However, jsonpCallback function is not called for me on successful response. You mentioned to use JSONP, when webservices support the callback parameter. I think my webservices doesn't support jsonp (because jsonpCallback function is not called for me in client side). Please correct me if I am wrong. As I don't have control over my server code (webservices), I can't change that webservice to handle jsonp type. is there anyother soultion for me to work on client side. Once again thanks for your time. –  Jan 22 '14 at 13:20
  • [`jsonp` doesn't work without a callback](http://stackoverflow.com/a/11812543/1520671), I don't think there is any other solution besides this. – Salman Jan 22 '14 at 13:36
  • Why don't you make a proxy method on your server which accepts your ajax requests, make requests to that web service? – Salman Jan 22 '14 at 15:43
  • I am talking about the same node server which runs your ajax code. Make a proxy function there which takes the requests from ajax and makes the request to webservice. cross domain limitations are in browser, not in node.js server, so you could easily access the web service and respond back its response. – Salman Jan 23 '14 at 04:38
  • In the post http://stackoverflow.com/questions/20323332/accessing-webservices-from-a-website-which-is-running-behind-a-proxy, it explained using http-proxy the cross domain limitations are fixed in node server. I followed the same code (available in his question) and now cross domain issue is fixed. Now, I have a similar proxy server setup between these two servers. Hence, with out proxy server, I can able to access webservices successfully. However, if I have a proxy server between website and webservice (servers), I am getting 500 Internal Server NetworkError. Can you please help me on this? –  Jan 23 '14 at 07:08