ajax post works vs. angularjs $http does not work

2019-06-24 05:21发布

I have two projects client side and server side. Client side project is pure htmljs. Server side is ASP.NET MVC 4 and Web Api. Because there are two projects I need to enable CROS functionality. I added into server's webconfig:

<system.webServer>
 <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

Ajax Post version which is working:

$.post(url, appContext).done(
                function(data, textStatus, jqXHR) {
                    successFn(data, textStatus);
                })
                .fail(
                    function(jqXHR, textStatus, err) {
                        errorFn(err, textStatus);
                    });

angular $http Post version which is NOT working:

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

When I use $http I am getting two errors:

  1. OPTIONS url 405 (Method Not Allowed)
  2. POST url 500 (Internal Server Error)

ASP.NET MVC method is

[System.Web.Http.HttpPost]
public List<Module> GetModules([FromBody]SessionContext appContext)
{
 return  CreateModules();
}

EDIT:

Angular model's configuration:

var emsApp = angular.module('EmsWeb', ['ui.bootstrap']);
emsApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {

    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);

Headers of OPTIONS request that I see in browser:

Request URL:http://localhost/EmsWeb/api/ModuleApi/GetModules?appContext=%7B%22globalDate%22%3A%22Mon%2C%2008%20Jul%202013%2013%3A09%3A35%20GMT%22%2C%22userToken%22%3A%22AlexToken%22%7D
Request Method:OPTIONS
Status Code:405 Method Not Allowed

Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:localhost
Origin:http://localhost:50463
Referer:http://localhost:50463/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Query String Parametersview sourceview URL encoded
appContext:{"globalDate":"Mon, 08 Jul 2013 13:09:35 GMT","userToken":"AlexToken"}

Response Headers
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:76
Content-Type:application/json; charset=utf-8
Date:Mon, 08 Jul 2013 13:09:35 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

Any ideas why angular way does not work are appreciated?

Update the issue as it turns out to be quite silly: because I used params and instead of data in:

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

angular converted to GetRequest. No need for ContentType either. so actual code is

 $http({method: 'POST',
            url: url,                
            data: appCtx,
        }).success(successFn).error(errorFn);

so ALMOST resolved, I see that angular still issues OPTIONS request that fails but post request goes through...

so any ideas on that one are appreciated

3条回答
beautiful°
2楼-- · 2019-06-24 05:24

My issue were due to two reasons: I used params and instead of data in

 $http({
                url: url,
                method: 'POST',
                params: { appContext: appContext },
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                    /*'Accept': 'text/json'*/}
            }).success(successFn).error(errorFn);

angular converted to GetRequest. No need for ContentType either. so actual code is

 $http({method: 'POST',
            url: url,                
            data: appCtx,
        }).success(successFn).error(errorFn);

on the server side I needed something handling OPTIONS request. One way is to decorate method w/ [System.Web.Http.AcceptVerbs("OPTIONS")], which I do not think the best way. Another way is to add Custom Message Handler. I am still researching it...

查看更多
混吃等死
3楼-- · 2019-06-24 05:26

If your ajax is working then it looks like the angular side of things isn't configured. Add this before you use $http (in your controller setup).

$http.defaults.useXDomain = true;

See this guys jsfiddle for a working example: http://jsfiddle.net/ricardohbin/E3YEt/

EDIT: Further to your comment and edit to the question, this post might help you: http://www.codeguru.com/csharp/.net/net_asp/using-cross-origin-resource-sharing-cors-in-asp.net-web-api.html

查看更多
Viruses.
4楼-- · 2019-06-24 05:31

-Be sure about the syntax of get and Post and the way of sending parameters -Check the expected Parameter that you expect at the destination action or method and be sure that the sending one and receiving one are the same.

查看更多
登录 后发表回答