2

I am new to angularjs and trying to consume wcf restful service using angularjs client.Initially I had tried for http.get(url) and got the CORS issue which I resolved by putting following code in my wcf service method which I want to call.

WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", ""); WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST,GET,OPTIONS"); WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");*

Now when I made a post call (http.post) the same way I did for get I got the response back with out CORS issue.

But when I tried to pass JSON object while make a post I again started getting CORS issue.

My angular code for post is:

 var requestData = {
            RequestUserName: "Abc1",
            RequestPass: "123"
        };

        var req = {
                    method: 'POST',
                    url: 'url',
                    headers: {
                        'Content-Type': 'application/json; charset=utf-8'
                    },
                    data: requestData
        };
         $http(req).success(function(){console.log("Success");
         $scope.userDetails = response.UserNameAuthenticationResult;}).error(function(){console.log("Error");});

My WCF operation contract looks as below:

 [WebInvoke(Method="POST",UriTemplate="/Authenticate"
           ,RequestFormat=WebMessageFormat.Json
           ,ResponseFormat=WebMessageFormat.Json
           ,BodyStyle = WebMessageBodyStyle.Wrapped)]

        string UserNameAuthentication(Request request);

and method implementation is below:

 public string UserNameAuthentication(Request request)
       {
         WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
       WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
      WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");

           return "true";
       }

And the error that I am getting is below:

**OPTIONS URL (anonymous function) @ angular.js:11442sendReq @ angular.js:11235serverRequest @ angular.js:10945processQueue @ angular.js:15552(anonymous function) @ angular.js:15568$eval @ angular.js:16820$digest @ angular.js:16636$apply @ angular.js:16928(anonymous function) @ angular.js:24551defaultHandlerWrapper @ angular.js:3398eventHandler @ angular.js:3386 localhost/:1 XMLHttpRequest cannot load http://localhost:8733/TestService/Login/Authenticate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:14703' is therefore not allowed access. The response had HTTP status code 405.

5
  • i think there is nothing to do with angularjs. You need to configure CORS in wcf application. check this out. Commented Nov 3, 2016 at 8:35
  • use this plugin : chrome.google.com/webstore/detail/allow-control-allow-origi/… Commented Nov 3, 2016 at 9:34
  • This did not help, I already tried putting the piece of code inside the calling method in wcf service but still same error. Also as I have built wcf service as class library I do not get option to add global.asax file, we do get it in wcf application though and because of it I am adding the Headers code in the calling method. Commented Nov 3, 2016 at 12:09
  • Arjun- I added the plugin and I did not get the above mentioned error but I got a new error which says net::ERR_CONNECTION_REFUSED. Commented Nov 3, 2016 at 12:15
  • It will be very helpful if someone can provide a sample solution considering the fact that I have built rest service as WCF service library and not WCF service application. Commented Nov 3, 2016 at 12:23

2 Answers 2

0

CORS is an interaction between the browser and also the server settings.

It would be useful to post both the request and the response headers.

I assume you are interacting with an API that is on a different domain such as api.example.com rather than www.example.com. It is up to the server to set the Access-Control-Allow-Origins response header. To allow all origins as a temporary measure, set it to "*" rather than an empty string, but soon you should set it to the actual origin of your site such as www.example.com

In reality, you probably don't want it open completely since it could be a security risk, someone could create a fake version of your site.

An easy way to avoid CORS all together is to use a proxy server. This way all requests go to same domain (both html and API). If running a Node app, you can use node-http-proxy or similar. This also avoids the preflight requests if you have custom headers or data. Preflight requests are the OPTIONS requests that you see on your API before the actual request.

Here is some more info on preflight behavior: https://www.soasta.com/blog/options-web-performance-with-single-page-applications/

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

4 Comments

Hi Derric, I have tried all possible ways to tackle this, but no luck. Not sure if there is some issue with my JSON object as if I post without JSON object it works fine. I have mentioned the way I am posting the data. Not sure if it is the correct way.
Can you copy paste the HTTP Calls from Chrome Developer Tools, then we can look at the headers and the response? Specifically, you might see both your call and a second call with the OPTIONS method. There are also tools like Fiddler and Moesif able to capture HTTP Calls for debugging if you don't have access to Chrome Dev Tools or in Production envs.
Request URL:localhost:8733/Design_Time_Addresses/TestService/Login/… Request Method:OPTIONS Status Code:405 Method Not Allowed Remote Address:[::1]:8733 Response Headers view parsed HTTP/1.1 405 Method Not Allowed Allow: POST Content-Length: 1565 Content-Type: text/html; charset=UTF-8 Server: Microsoft-HTTPAPI/2.0 Date: Sat, 05 Nov 2016 13:33:10 GMT
Request Headers view source Accept:*/* Accept-Encoding:gzip, deflate, sdch, br Accept-Language:en-GB,en-US;q=0.8,en;q=0.6 Access-Control-Request-Headers:content-type Access-Control-Request-Method:POST Connection:keep-alive Host:localhost:8733 Origin:localhost:14703 Referer:localhost:14703 User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
0

Looks like CORS is not enabled on server side since the OPTIONS method is not understood.

Maybe try this:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE, OPTIONS");

        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}

2 Comments

As I am using WCF service library I could not add Global.asax file, it can be added in WCF service application. However I have added the mentioned piece of code in my calling method which resolves my issue when I make a post request without a JSON object but my problem occurs when I make a post request with JSON object. I have mentioned the way I making a post request in my Question at the top.
Can you paste your updated HTTP logged call, that helps for debug.

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.