19

Background:- I created a WCF service hosted in my local system IIS. Service exposes GET/POST method and cross domain enabled and can be accessed using https too. To make it accessible, self signed certificate is used.

Testing:- When i try to do cross domain ajax call it work fine for GET request and POST request (only those post method which are not accepting data as a json) in IE10/Edge. I'm able to make cross domain call for any GET/POST request in chrome/Firebox browser. Only it's IE 10/Edge which cause problem to make cross domain call for POST request when contenttype:accept/json parameter is passed in ajax call.

Research:- I read lots of blogs/mdn and get to know specification of cors in which IE does not follow cors religiously. I know cors specification does not alloe custom header/header's value due to which cors preflight aborted.

Example of ajax request i'm making:-

var postDT = { "postValue": "test" };
        debugger;
        $.support.cors = true;
        $.ajax({
            type: "POST",
            data: JSON.stringify(postDT),
            url: "http://ateet3371/Service1.svc/postdata",
            contentType: "application/json; charset=utf-8",
            dataType: "JSON",
            processData: true,
            success: function (data) {
                 alert(data);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                var a = jqXHR;
                alert(jqXHR + '---' + textStatus + '---' + errorThrown);
            }
        });

If i removed contentType: "application/json; charset=utf-8" then it throw bad request error else it throw access denied error.

And method implementation in WCF is:-

[OperationContract]
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostResponseData")]
    string PostResponseData(PostDataTest postDT);

And datacontract is:-

[DataContract]
public class PostDataTest
{
    private string post_value;

    // Apply the DataMemberAttribute to the property.
    [DataMember]
    public string postValue
    {

        get { return post_value; }
        set { post_value = value; }
    }
}

If i use method PostUrl data then ajax call is executed successfully and return proper results if ContentType:"Application/json" header is removed from request.

[OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostUrlData/{value}")]
    string PostUrlData(string value);

I already write code in BeginRequest event in Global.asax of WCF to handle Options request:-

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, HEAD");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, X-Requested-With, Session");
        HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "DAV, content-length, Allow" );
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000" );
        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache,no-store");
        HttpContext.Current.Response.End();
        } 

And i can't enable Allow cross domain call setting in IE as end user would not do such steps.

Stuck in Problem:- But still not able to do JSON data post call in IE 10/Edge (which are cors enabled).

(Edited) Updates: IIS site where WCF is hosted have only Anonymous Authentication enabled while other authentication are disabled. Even I tried with valid certificate for https but still it is not working for IE but work perfect for chrome.

Request Header

OPTIONS https://service.domian.com/projectservice.svc/GetMultiListData HTTP/1.1 Accept: */* Origin: https://sitename.servicedomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type, accept Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Host: sitename.servicedomain.com Content-Length: 0 Connection: Keep-Alive Cache-Control: no-cache

Response Headers

HTTP/1.1 200 OK Cache-Control: no-cache,no-store Server: Microsoft-IIS/7.5 Access-Control-Allow-Origin: sitename.servicedomain.com Access-Control-Allow-Methods: GET,POST,PUT,HEAD Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Origin,Content-Type,Accept,X-Requested-With,Session Access-Control-Expose-Headers: DAV,content-length,Allow Access-Control-Max-Age: 1728000 X-Powered-By: ASP.NET Date: Thu, 04 Aug 2016 17:26:27 GMT Content-Length: 0

Please help me as I go through lots of article and blog and still not able to resolve the issue. Your help will be greatly appreciated!

EXPERT's PLEASE HELP ME!

ateet
  • 241
  • 2
  • 8
  • Does changing dataType to "jsonp" allow the request? – Jake Bown Jul 29 '16 at 15:48
  • Did you try api fetch instead of $.ajax ? Fetch is the new standar. https://www.todojs.com/api-fetch-el-nuevo-estandar-que-permite-hacer-llamadas-http/ – toto Jul 17 '20 at 14:09

2 Answers2

0

There are a few things you can check client-side:

  • you're trying to override $.support.cors. This is (or was) meant to be a readable property telling you if CORS is supported by the browser. (see jQuery source for where this is checked)
  • Based on jQuery docs for ajax you might want to add xhrFields: { withCredentials: true } to the $.ajax() options
  • Use correct casing of dataType: "json" and charset=UTF-8

At server-side, you may want to try responding with specific hostname (echo the Origin header) instead of wildcard (*) in the Access-Control-Allow-Origin response header. This is specifically mentioned in MDN in a paragraph also discussing Access-Control-Allow-Credentials:

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *.

searlea
  • 8,173
  • 4
  • 34
  • 37
  • I removed $.support.cors as it is already true, corrected the syntax for datatype and charset. And set the Access-Control-Allow-Origin specific to domian from where i'm calling service. But still it doesn't work. – ateet Aug 03 '16 at 06:58
  • Can you share the code you're using to set Access-Control-Allow-Origin - just to confirm its present on both pre-flight and real request, as well as checking its content (either echoing `Origin`, or hard-coded to include the right `http://` vs `https://` protocol.) I also wonder if you're seeing any problems in IE10 / Edge if you use a service like [test-cors.org](http://test-cors.org/)? – searlea Aug 03 '16 at 08:45
  • How should i share you the code? I mean your any id where i can share you? – ateet Aug 03 '16 at 16:17
  • I suggest editing/updating the code in the question (If you need to censor a host-name, just use 'example.com', but it's important you don't change syntax - i.e. `http://www.google.com/` would become `http://example.com/`, not `http://example.com`, `https://example.com/` or plain `example.com`. – searlea Aug 04 '16 at 16:27
  • I updated the request and response header which am getting from fiddler. – ateet Aug 04 '16 at 17:39
  • Your `Access-Control-Allow-Origin` response header appears to be missing the protocol: `https://` (based on request `Origin`) – searlea Aug 06 '16 at 08:54
  • Sorry for late response, but i tried with both cases i.e. with https:// and without https but it doesn't work. – ateet Aug 10 '16 at 07:54
0

It's not a long term solution, but you could check out https://cors-anywhere.herokuapp.com/ You can GET or even POST data without issue through this. Include their link before your URL so https://cors-anywhere.herokuapp.com/http://ateet3371/Service1.svc/postdata and set that as the URL value in your ajax. Like I said, it's not a long term solution but if it works then see what you can do from there.

I wish I could be of more assistance. Good luck!