Implement jquery. ajax and native XMLHttpRequest to call the WCF Service across domains. jquery. ajaxwcf

Source: Internet
Author: User

Implement jquery. ajax and native XMLHttpRequest to call the WCF Service across domains. jquery. ajaxwcf

There are many methods for ajax cross-origin calling of the WCF Service. After repeated code tests, I think the following method is the easiest, and of course it cannot be said that others' methods are wrong, the following is the code. The WCF Service definition is still extended, for example:

Namespace WcfService1 {[ServiceContract] public interface IAddService {[OperationContract] [WebInvoke (Method = "GET", RequestFormat = WebMessageFormat. json, ResponseFormat = WebMessageFormat. json, BodyStyle = WebMessageBodyStyle. wrappedRequest)] int Add2 (int a, int B) ;}} namespace WcfService1 {[AspNetCompatibilityRequirements (RequirementsMode = AspNetCompatibilityRequirementsMode. allowed)] // [JavascriptCallbackBehavior (UrlParameterName = "jsoncallback")] // use the default callback parameter public class AddService: IAddService {public int Add2 (int, int B) {return a + B ;}}}

Create a WCF Service file with the following content:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.AddService" %>

The above implementation supports GET method request calling. The following is the configuration of WEB. CONFIG to support cross-origin calls. Note that I have commented out standardEndpoints. Of course, if you do not comment it, it will not affect it. The key is the attribute in the bindings node: crossdomainscriptaccessential abled = "true ", as follows:

<System. serviceModel> <! -- <StandardEndpoints> <webHttpEndpoint> <standardEndpoint endpoints = "true"/> </webHttpEndpoint> </standardEndpoints> --> <serviceHostingEnvironment endpoints = "true"/> <bindings> <webHttpBinding> <binding crossdomainscriptaccessential abled = "true"> </binding> </webHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior> <! -- To avoid metadata leakage, set the following value to false before deployment and delete the above metadata endpoint --> <serviceMetadata httpGetEnabled = "true"/> <! -- To receive fault exception details for debugging, set the following value to true. Set false before deployment to avoid leakage of exception information --> <serviceDebug includeExceptionDetailInFaults = "true"/> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name = "AddServiceBehavior"> <enableWebScript/> </behavior> </endpointBehaviors> </behaviors> <services> <service name = "WcfService1.AddService"> <endpoint address = "" binding = "webHttpBinding" contract = "WcfService1.IAddService" behaviorConfiguration = "AddServiceBehavior"> </endpoint> </service> </services> </system. serviceModel>

Create the Global. asax file and add the following code:

        protected void Application_BeginRequest(object sender, EventArgs e)        {            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);            HttpContext.Current.Response.Cache.SetNoStore();            EnableCrossDmainAjaxCall();        }        private void EnableCrossDmainAjaxCall()        {            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")            {                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",                              "GET, POST");                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",                              "Content-Type, Accept");                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age",                              "1728000");                HttpContext.Current.Response.End();            }        }

The following is the code for cross-origin calling of the WCF Service on the WEB Client.

1. Use native XMLHttpRequest to call the WCF Service across domains:

// Simple encapsulation of var $ = function (id) {return document. getElementById (id) ;}; function getXMLHTTPRequest () {var req = false; try {req = new XMLHttpRequest ();} catch (err) {try {req = new ActiveXObject ("Msxml2.XMLHTTP");} catch (err) {try {req = new ActiveXObject ("Microsoft. XMLHTTP ") ;}catch (err) {req = false ;}}return req ;}// The following is a button click event. synchronous call is used, of course, the callback method can also be used. If the callback method is used, you need to add: callback = callback Method to the request URL, and then define a callback method $ ("btnGet "). onclick = function () {var querystr = "a =" + $("num1 "). value + "& B =" + $("num2 "). value; var xmlhttp = getXMLHTTPRequest (); xmlhttp. open ("GET "," http://localhost:30348/addservice.svc/Add2 ? "+ Querystr, false); xmlhttp. send (); var r = eval ("(" + xmlhttp. responseText + ")"); $ ("result "). value = r. d ;}

 

 

2. The original cross-origin method can be implemented by dynamically requesting WCF Address Resources in JS mode. Although cross-origin calling can be implemented, only the GET method is supported. If POST is supported, no solution is available:

$ ("BtnGet "). onclick = function () {var querystr = "a =" + $("num1 "). value + "& B =" + $("num2 "). value; var script = document. getElementById ("crossDomainScript_wcf") | document. createElement ("script"); script. type = "text/javascript"; script. id = "crossDomainScript_wcf"; script. src = "http: // localhost: 30348/addservice. svc/Add2? Callback = success_callback & "+ querystr; document. getElementsByTagName ("head") [0]. appendChild (script);} // callback method function success_callback (data) {$ ("result "). value = data ;}

The following is a POST call:

        $("btnGet").onclick = function () {            var xmlhttp = getXMLHTTPRequest();            xmlhttp.open("POST", "http://localhost:30348/addservice.svc/Add2", true);            xmlhttp.setRequestHeader("Content-Type", "application/json");            xmlhttp.onreadystatechange = function () {                alert(xmlhttp.status);                if (xmlhttp.readyState == 4) {                    if (xmlhttp.status == 200) {                        var r = eval("(" + xmlhttp.responseText + ")");                        $("result").value = r.d;                    }                }            };            xmlhttp.send('{"a":' + $("num1").value + ',"b":' + $("num2").value + '}');        }

2. Use jQuery. ajax to call:

        var jq = jQuery.noConflict();        jq("#btnGet").click(function () {            jq.ajax("http://localhost:30348/AddService.svc/Add2", {                type: "get",                dataType: "jsonp",                data: 'a=' + jq("#num1").val() + '&b=' + jq("#num2").val(),                success: function (data) {                    jq("#result").val(data);                },                error: function (x, textStatus, errorThrown) {                    alert("error:" + textStatus);                }            });        });

In fact, JSONP can be called directly in normal mode, because the WCF server already supports cross-origin calls:

        var jq = jQuery.noConflict();        jq("#btnGet11").click(function () {            jq.ajax("http://localhost:30348/AddService.svc/Add2", {                type: "GET",                dataType: "json",                data: 'a=' + jq("#num1").val() + '&b=' + jq("#num2").val(),                success: function (data) {                    jq("#result").val(data.d);                },                error: function (x, textStatus, errorThrown) {                    alert("error:" + textStatus);                }            });        });

  

Of course, you can also use JSON when passing parameters (note that the POST and get json statements are different, the key value must be a strict JSON string for POST and a JS object for GET ), I will not describe it here

POST call:(Pay attention to the JQUERY. AJAX adopts the JSONP + GET mode and is not applicable to the POST mode. After debugging, it is found that the JSONP mode is used and the GET request is initiated at the end. The principle is the original cross-origin call method I wrote above)

        var jq = jQuery.noConflict();        jq("#btnGet").click(function () {            jq.ajax("http://localhost:30348/AddService.svc/Add2", {                type: "POST",                dataType: "json",                contentType: "application/json",                data: '{"a":' + jq("#num1").val() + ',"b":' + jq("#num2").val() + '}',                success: function (data) {                    jq("#result").val(data.d);                },                error: function (x, textStatus, errorThrown) {                    alert("error:" + textStatus);                }            });        });

Here, we will make a special note on cross-origin requests. If AJAX is used for cross-origin calls, two requests will be sent. The first request is OPTIONS, which is used for server pre-check and the second request will be sent, this is why the Global of the WCF Service. why does asax need to add EnableCrossDmainAjaxCall. I have taken many detours and tried many methods when I studied cross-origin WCF calling, but I still figured it out. I hope you can benefit from this blog post. What are the shortcomings in this article, thank you!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.