0

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.

4

2 回答 2

1

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.

于 2013-07-23T00:55:54.483 回答
0

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.

于 2013-07-23T01:29:44.777 回答