1

I'm assembling my first AngularJS app. My controller is making a $http.get() call. The url it's using is correct, but it ends up calling the "error" method with a 404. This is even more confusing when I see the URL being requested in Firebug, and it reports a 200.

I don't think I need to show the html for this. I can't imagine how that could be relevant.

Here's my somewhat elided javascript:

var diagapp = angular.module("DiagApp", ['ui.bootstrap', 'ngResource']);

diagapp.controller("DiagCtrl", ['$scope', '$interval', '$http', function($scope, $interval, $http) {
$http({method:'GET',url:'http://<hostportandpath>/service/diagnostics/datasourceStatus.json'})
    .success(function (data, status, headers, config) {
        console.log(data);
    })
    .error(function (data, status, headers, config) {
        console.log(data);
    });
}]);

I've tried setting a breakpoint at the "$http" line, and then copying and pasting the URL referenced on that line into another browser tab, and it shows me the correct json returned by that service. I then continue from the breakpoint, and it hits the breakpoint in the "error" method, and the status says 404.

What could I be doing wrong?

Update:

I've modified this so that the service call is only relative, so it doesn't violate the CDP.

I also set up a "node express" web server running at the root of my webapp, so it will serve requests for files in the webapp, but any calls to the REST service are 302-redirected to the service on another domain.

When I debug this in Firebug, I see it get the 302, and then I see it get the 200, so it obviously followed the redirect. However, it then hits the breakpoint in the "error" method, still saying it got a 404. In other words, I get the exact same result. I'm befuddled.

Update:

Here is my slightly elided "express server" configuration:

var express = require('express');
var app = express();

app.use("/", express.static(__dirname));
app.use(app.router);

app.get('/FooService/*', function(req, res) {
res.redirect(302, 'http://<hostname>' + req.path);
});

app.listen(8000);
1
  • if your service requires anysort of authentication (or even has CORS enabled) you can set withCredentials:true in the $http config object and it will send an OPTIONS preflight Commented Feb 9, 2014 at 7:25

1 Answer 1

2

I think you're getting an error because you're making a request to a different domain violating the Same Origin Policy (http://en.wikipedia.org/wiki/Same-origin_policy). Instead you should make a request to a server on you own domain and have that server provide the data you need (possibly by cacheing it from the other domain). Or you can use JSON-P and have the other domain your calling call a method on your client side.

Update

So to create the express server we first use the http library to make a request to get the json data we want and we store the response in the variable data. Then we setup our webserver just like you did except instead of responding with a redirect we respond with the data itself.

var express = require('express');
var http = require("http");
var app = express();
var data;

// Make the request to buffer the data
var options = {
    host: 'somesite.com',
    port: 1337,
    path: '/some/path',
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    }
};

var req = http.request(options, function(res)
{
    var output = '';

    res.on('data', function (chunk) {
        output += chunk;
    });

    res.on('end', function() {
        data = JSON.parse(output);
    });
});

req.on('error', function(err) {
    //res.send('error: ' + err.message);
});

req.end();

// Start the webserver to respond with the data

app.use("/", express.static(__dirname));
app.use(app.router);

app.get('/FooService/*', function(req, res) {
    response.writeHead(200, { 'Content-Type': 'application/json'});
        response.end(data);
});

app.listen(8000);

Note I haven't been able to test this all yet so you may need to make some adjustments, but I have done very similar things with Node, Express and Angular and I'm sure this type of thing will work. You may want to adjust how often the data is cached on your server by putting the request in a setTimeout or making the request on demand in the app.get method (but that would be slower). You can read more about http.request() here: http://nodejs.org/api/http.html#http_http_request_options_callback

Sign up to request clarification or add additional context in comments.

6 Comments

Ok, I'm familiar with the same-origin policy, I guess I had some illusion that $http could get around that. I guess I'm going to look at using "node express" or some other way to build a simple configurable proxy.
Ok, so I did a bunch of work to set up a "node express" web server, so it would serve the local files from my webapp, but redirect calls to the relative path to the REST service to a server that can serve that. I tested this with raw calls with "wget", and it worked fine. In Firebug, I see it get the 302, and then the 200, and then it its the breakpoint in the "error" method showing a 404. I made it a relative path and set it up so it would call the actual service, but the result is identical. It hits the error method for some reason that I can't understand.
So does both success and error callbacks get called or just error? Have you tried just getting a static json file on the same directory as your js code? Maybe you could update the question with the express server?
Only the error callback gets called. I'll update the post with my express server config.
Ahh I see. Yeah Angular is expecting a response containing some kind of data. Responding with a 302 redirect isn't going to work. I updated my answer with the way I think you should do it. Basically the JSON data needs to come from your server.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.