问题
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!
回答1:
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"
andcharset=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: *.
来源:https://stackoverflow.com/questions/38451753/post-json-ajax-request-with-cors-not-working-in-ie10-edge