Web API Implementation JSONP or install configure cors across domains

Source: Internet
Author: User
Tags script tag unique id

Objective

Logically speaking, this section should also talk about the principle of Web API, has been discussed in the comparison of the underlying Web API message processing pipeline and the web host Homestay pipeline, the next should be to touch the Controller, action method, and filter, model binding and so on, think also heartache unceasingly, the water is too deep, Groping principle is too dull and boring, but, from the emotional or is very happy to explore the principle, and emotional not too happy to explore the principle, so, this article was born, by this text to alleviate the dull mood and depressed mood. Continue to explore the principle of follow-up.

The next thing we want to talk about is the use of JSONP and the use of cors in two ways to achieve cross-domain, see below .....

Jsonp Implementing Cross-domain

The Web API does not provide JSONP Formatter, but this does not affect our progress, and we can customize the Formatter to implement the JSONP functionality. Since the use of Jsonp cross-domain, then you have to briefly introduce the next JSONP.

Why do I need JSONP?

Browsers are based on the same-origin policy, so that their scripts can not cross the site to obtain server-side data, but the approach is always people think out, this time need to JSONP, of course, can also be implemented in other ways, Jsonp is a way to get data from a non-current server by enabling JavaScript-based client programs to bypass the cross-site scripting restrictions. By default, applications take advantage of Ajax to not allow access to remote cross-domains, but we can use the <script> tag to load JSONP to implement this cross-site limitation. This is also a good solution. JSONP works by combining JSON data and wrapping it into a function when the JSON data is returned, and using jquery to do this better.

If there is a URL such as the following:

http://www.cnblogs.com/CreateMyself/WebAPI/xpy0928

But we use Ajax to make a GET request to get server-side data that would be a breeze, but, however, the important premise is three times, assuming that under the same domain, if different domains, using AJAX to access data estimation is not so easy. But, however, the important thing to say three times, when we use JSONP to achieve cross-domain, this will become the following request mode:

Http://www.cnblogs.com/CreateMyself/WebAPI/xpy0928?callback=?

Send the following URL request through a callback callback, so that the result is consistent with the results of the same site, jquery will deserialize the data and push it into the function.

What is the JSONP data?

The main thing is to wrap the returned JSON data by calling the function, similar to the following form:

QUERY7D59824917124EEB85E5872D0A4E7E5D ([{"Id": "123", "Name": "xoy0928"},{...}])
How does the JSONP work?

After a request is made by a JavaScript client, its data is used as the parameter for executing the function to be called, and the JSON data is deserialized inside the response data

Let's take a look at the following code to illustrate the principle:

    function JSONP (URL, callback) {        var id = "_" + "Query" + (new Date ()). GetTime ();  Create an almost unique ID                window[id] = function (result) {  //Create a global callback handler            if (callback)                callback (result);            var getId = document.getElementById (ID);  Remove the script tag and ID            getId.parentNode.removeChild (getId);            Window[getid] = null;        }        url = url.replace ("callback=?", "callback=" + ID);        var script = document.createelement ("script");  Create a script tag and execute window[id] function        script.setattribute ("id", id);        Script.setattribute ("src", url);        Script.setattribute ("type", "Text/javascript");        Document.body.appendChild (script);    }

The simple invocation is as follows:

function Jsonpfunction () {                JSONP ("http://localhost:23133/api/default?callback=?",                function (jsondata) {          //Jsondata The returned data as a parameter of the calling function        }};
How is JSONP implemented in the Web API?

The above mentioned JSONP principle and implementation, then how to combine the Web API is implemented? We can only customize the formatter to implement this function manually, since there is a JSON, then naturally inherited from the Jsonmediaypeformatter, the code is as follows:

The first step

Custom Jsonpformatter and inherit from Jsonmediatypeformatter:

public class Jsonpformatter:jsonmediatypeformatter {//When the request comes up is with text/javascript when processing JSONP request public Jsonpforma            Tter () {Supportedmediatypes.add (New Mediatypeheadervalue ("Application/json"));            Supportedmediatypes.add (New Mediatypeheadervalue ("Text/javascript"));        Jsonpparametername = "Callback"; }
Lookup function name public string Jsonpparametername {get; set;} private string jsonpcallbackfunction; public override bool Canwritetype (type type) {return true; }
Override this method to capture the request object public override Mediatypeformatter getperrequestformatterinstance (type type, SYSTEM.NET.HTTP.HTTPREQ Uestmessage request, Mediatypeheadervalue mediatype) {var formatter = new Jsonpformatter () { Jsonpcallbackfunction = getjsoncallbackfunction (Request)};
Use Json.NET to serialize your custom formatter. SERIALIZERSETTINGS.CONVERTERS.ADD (New Stringenumconverter ()); Formatter. serializersettings.formatting = Newtonsoft.Json.Formatting.Indented; return formatter; }//Override this method to write to the stream and return public override Task Writetostreamasync (type type, object value, Stream stream, httpcontent content, TransportContext transportcontext) {if (string. IsNullOrEmpty (jsonpcallbackfunction)) return base. Writetostreamasync (type, value, stream, content, transportcontext); StreamWriter writer = null; try {writer = new StreamWriter (stream); Writer. Write (Jsonpcallbackfunction + "("); Writer. Flush (); } catch (Exception ex) {try { if (writer! = null) writer. Dispose (); } catch {} var TCS = new taskcompletionsource<object> (); Tcs. SetException (ex); Return TCS. Task; } return base. Writetostreamasync (type, value, stream, content, TransportContext). ContinueWith (Innertask = {if (Innertask.status = = taskstatus.rantocom Pletion) {writer. Write (")"); Writer. Flush (); }}, taskcontinuationoptions.executesynchronously). ContinueWith (Innertask = {writer. Dispose (); return innertask; }, taskcontinuationoptions.executesynchronously). UnWrap (); }
Get the JSONP callback callback function from the query string private string getjsoncallbackfunction (Httprequestmessage request) { if (Request. Method! = Httpmethod.get) return null; var query = httputility.parsequerystring (request. Requesturi.query); var queryval = Query[this. Jsonpparametername]; if (string. IsNullOrEmpty (queryval)) return null; return queryval; } }
Step Two

You should register this custom class at this point:

            Globalconfiguration                . Configuration                . Formatters                . Insert (0, New Jsonpformatter ());
Step Three

Give the background test data:

    public class person    {public        string Name {get; set;}        public int Age {get; set;}        public string Gender {get; set;}    }        Public ienumerable<person> Getallperson ()        {            person[] person = new person[]            {                new person{name= " xpy0928 ", Age =11, gender=" Male "},                new person{name=" xpy0929 ", Age =12, gender=" female "},                new person{name=" xpy0930 ", A GE =13, gender= "Male"},           };            return person;        }

The next step is to verify. Call the Jsonp method written by the above foreground:

     function Getperson () {        JSONP ("http://localhost:23133/api/default?callback=?",              function (persons) {                  $. Each (persons, function (index, person) {                      var html = "<li><ul>";                      HTML + = "<li>name:" + person. Name + "</li>";                      HTML + = "<li>age:" + person. Age + "</li>";                      HTML + = "<li>gender:" + person. Gender + "</li>";                      HTML + = "</ul>";                      $ ("#person"). Append ($ (HTML))    ;});}; $ (function () {        $ ("#btn"). Click (function () {            getperson ();        });    });

The above can also use Ajax to request, the following are necessary:

        $.ajax ({                type: "Get",                URL: "http://localhost:23133/api/default/?callback=?",                DataType: "JSON",                ContentType: "Application/json; Charset=utf-8 ",
.......
})

Click Load Data:

<input type= "button" value= "Get Data" id= "BTN"/><ul id= "person" ></ul>

Since it is cross-site to open two applications on the chant, server side: localhost:23133, client: localhost:29199, walk you, finished:

Summarize

All is well concluded, it seems that using JSONP to achieve cross-domain is a good solution, but some people ask, JSONP also have limitations ah, only for GET request can not be used for POST request Ah, and also need to manually write such a fucking code, a bit heinous, yes, it is really a problem, You think of at the same time I also think for you, please see below!

Cors implements cross-domain

Using Cors for cross-domain configuration is extremely straightforward, but only if you have to download the package through NuGet, search for the package "Microsoft.AspNet.WebApi.Cors",

When the download is complete, there are two ways to configure cross-domain

First

Global configuration in the Web API configuration file:

            var cors = new Enablecorsattribute ("*", "*", "*");            Config. Enablecors (cors);
Second

If you just want a controller to apply cross-domain, that is, to implement a local controller cross-domain, you can, of course, add features to achieve this:

   [Enablecors (Origins: "*", Headers: "*", Methods: "*")]    public class Homecontroller:controller    {    }
Try (i)

In the Web API configuration file of the requested server side, full-text configuration, the next post request is as follows:

        $ ("#btn"). Click (function () {            $.ajax ({                type: "POST",                URL: "http://localhost:23133/api/Default/ Postallperson ",                dataType:" JSON ",                contentType:" Application/json; Charset=utf-8 ",                Cache:false,                success:function (persons) {                    $.each (persons, function (index, person) {                        var html = "<li><ul>";                        HTML + = "<li>name:" + person. Name + "</li>";                        HTML + = "<li>age:" + person. Age + "</li>";                        HTML + = "<li>gender:" + person. Gender + "</li>";                        HTML + = "</ul>";                        $ ("#person"). Append ($ (HTML));});});        

As we expect, the test passes:

Try (ii)

Make a local configuration on the controller and issue a GET request, modified as follows:

    [Enablecors (Origins: "*", Headers: "*", Methods: "*")]    public class Defaultcontroller:apicontroller    {public        ienumerable<person> Getallperson ()        {}    }

The request is made as follows:

     $.ajax ({                type: "Get",                URL: "Http://localhost:23133/api/Default",                dataType: "JSON",                ...).           })

We check the request header information and return the status code to know if it is successful as follows (as expected):

The test exploits cors for both get and post requests, and it is very friendly to return the data for the response and to configure it easily. Of course, the functionality of Cors is much more than simple, more details, see "Cors-origin for WebAPI"

Summarize

Using JSONP to achieve a better cross-domain on the Web API, but there are two serious flaws, the first: only get requests. Second: You have to customize the implementation jsonmediatypeformatter. You have no better solution before Cors is born, you can only endure, since the advent of cors, we are no longer subject to the requirements of the request, no more manual implementation, just a little configuration to achieve what we need, so using cors to implement cross-domain will be an irreplaceable solution.

Ext.: http://www.cnblogs.com/CreateMyself/p/4836628.html

Web API Implementation JSONP or install configure cors across domains

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.