On cross-domain support of cross-domain with WebService

Source: Internet
Author: User
Tags basic html page

Cross-domain problems originate from JavaScript's same-origin policy, which allows mutual access only if the protocol + host name + port number (if present) is the same. This means that JavaScript can only access and manipulate resources under its own domain, and cannot access and manipulate resources under other domains.

In the past, front-end and back-end mixed together, such as JavaScript directly invoke a HttpHandler inside the system, there is no cross-domain problem, but with the modern multi-client popular, such as an application will usually have web-side, app-side, and webapp-side, Various clients often use the same set of background processing logic, API, the development strategy of the front-end separation is popular, the frontend only focus on the presentation, usually using JavaScript, back-end processing logic and data often use WebService to provide JSON data. Generic front-end pages and back-end WebService APIs are typically deployed on different servers or domain names. This way, when the webservice is requested by Ajax, there is a problem of homologous policy.

It should be explained that the same-origin strategy is a limitation in JavaScript, other programming languages, such as C#,java or iOS and other languages can be called external webservice, that is, if the development of native application, there is no problem, However, if you develop a Web or Html5 such as webapp, you typically use JavaScript Ajax to initiate a request to webservice and then parse the returned value so that there may be a cross-domain problem.

In general, it is easy to think that moving external resources to the same domain will solve the same-origin policy limitations. That is, the Web site on the development of an HTTP Server page, all JavaScript requests are sent to this page, the page in the internal use of other languages to invoke external webservice. That is, add an agent layer. This approach solves the problem, but is not straightforward and efficient.

Currently, a more common cross-domain solution includes JSONP (JSON with padding) and cors (cross-origin resource sharing). Some solutions require client and server-side mates such as Jsop, and some require server-side coordination such as Cors. These two cross-domain scenarios are described below, and how the server-side webservice supports both cross-domain scenarios.

Support from JSONP and WebService

Under the same-origin policy, a server cannot get data outside the server, but tags such as img,iframe and script inside HTML are exceptions, which can be requested through the SRC attribute to data on other servers. The JSONP is called cross-domain requests through the script node src.

When we submit a JSONP request to the server, we pass a special parameter to the service, telling the service to treat the result in a special way. The data returned by the server is then packaged in a bit, which the client can handle.

For example, the server and client conventions are to pass a parameter named callback to use the JSONP feature. For example, the requested parameters are as follows:

1 http://www.example.net/sample.aspx?callback=mycallback

If there is no subsequent callback parameter, that is, the JSONP mode is not used, the return result of the service may be a purely JSON string, such as:

1 { foo : ‘bar‘ }

If the JSONP format is agreed with the server, the server will handle the callback parameters and return the results for processing, such as:

1 mycallback({ foo : ‘bar‘ })

As you can see, this is actually a function call, such as the implementation of a callback function named Mycallback in the page definition:

1234 mycallback = function(data)        {           alert(data.foo);        };

Now, the return value of the request goes back to triggering the callback function, which ends the cross-domain request.

If you use Servicestack to create a webservice, the call to support JSONP mode is simple, just register it in the Configure function of Apphost and filter the response results.

12345678910111213141516171819 /// <summary>        /// Application specific configuration        /// This method should initialize any IoC resources utilized by your web service classes.        /// </summary>        /// <param name="container"></param>        public override void Configure(Container container)        {            ResponseFilters.Add((req, res, dto) =>            {                var func = req.QueryString.Get("callback");                if (!func.isNullOrEmpty())                {                    res.AddHeader("Content-Type", ContentType.Html);                    res.Write("<script type=‘text/javascript‘>{0}({1});</script>"                        .FormatWith(func, dto.ToJson()));                    res.Close();                }            });        }

JSONP cross-domain approach is convenient, but also support a variety of older browsers, but the shortcomings are obvious, he only support get way to commit, do not support other post submissions, get way to request the length of the parameters are limited, in some cases may not meet the requirements. So here's a look at the cross-domain solution for cors.

Cors cross-domain and webservice support

Let's take a look at an example, and we'll create a basic HTML page to write a simple script that supports cross-domain, as follows:

1234567891011121314151617181920212223242526272829303132333435363738394041 <html xmlns="http://www.w3.org/1999/xhtml"><head>  <title>AJAX跨域请求测试</title></head><body>  <input type=‘button‘ value=‘开始测试‘ onclick=‘crossDomainRequest()‘ />  <div id="content"></div>   <script type="text/javascript">    //<![CDATA[    var xhr = new XMLHttpRequest();    var url = ‘http://localhost:8078/json/ShopUserLogin‘;    function crossDomainRequest() {      document.getElementById("content").innerHTML = "开始……";      if (xhr) {        xhr.open(‘POST‘, url, true);        xhr.onreadystatechange = handler;        xhr.send();      } else {        document.getElementById("content").innerHTML = "不能创建 XMLHttpRequest";      }    }    function handler(evtXHR) {      if (xhr.readyState == 4) {        if (xhr.status == 200) {          var response = xhr.responseText;          document.getElementById("content").innerHTML = "结果:" + response;        } else {          document.getElementById("content").innerHTML = "不允许跨域请求。";        }      }      else {        document.getElementById("content").innerHTML += "执行状态 readyState:" + xhr.readyState;      }    }    //]]>  </script> </body></html>

Then save as a local HTML file, you can see that in this script, the Local Service Http://localhost:1337/json/Hello initiated a request, if using chrome directly open, you will see the results of the output, do not allow cross-domain requests. You can also see the error message in the JavaScript console program:

Then if you inject Access-control-allow-origin in the header of the return response header, so that the browser detects the Access-control-allow-origin in the header, you can operate across domains.

Similarly, if you use Servciestack, you can support cors cross-domain mode in many places. The simplest is to write directly in Apphost's configure function:

123456789 /// <summary>/// Application specific configuration/// This method should initialize any IoC resources utilized by your web service classes./// </summary>/// <param name="container"></param>public override void Configure(Container container){    this.AddPlugin(new CorsFeature());}

This is done, which is equivalent to using the default Cors configuration:

1234 CorsFeature(allowedOrigins:"*", allowedMethods:"GET, POST, PUT, DELETE, OPTIONS", allowedHeaders:"Content-Type", allowCredentials:false);

If you allow cors only for Get and post requests, you only need to change to:

1 Plugins.Add(new CorsFeature(allowedMethods: "GET, POST"));

Of course, you can also set the global cors in Apphost Config, as follows:

1234567891011121314151617 /// <summary>/// Application specific configuration/// This method should initialize any IoC resources utilized by your web service classes./// </summary>/// <param name="container"></param>public override void Configure(Container container){    base.SetConfig(new EndpointHostConfig    {        GlobalResponseHeaders = {            { "Access-Control-Allow-Origin", "*" },            { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },            { "Access-Control-Allow-Headers", "Content-Type" },                },    });}

Now run WebService, use postman or Chrome to call this request, you can see the returned value header file, has been added to the response header, and can display the return result is normal:

Cors is simple to use, does not require additional processing by the client, and it supports post submission requests, but the only disadvantage of cors is that the browser version of the client is required, and the browser machine version that supports cors is as follows:

Summarize

This article introduces the basic concepts and causes of cross-domain in JavaScript, and how to solve the two methods of cross-domain, one is JSONP, one is CORS, when the client-side JavaScript calls the server interface, if need to support cross-domain, it needs service-side support. The Jsonp way is that the service side is wrapping the callback function on the returned value, and his advantage is that it supports a number of browsers, and the disadvantage is that only the get is supported in the way of the server request. Another mainstream cross-domain scenario is cors, which only requires the server to include identity information in the corresponding header when returning data. This is a very simple approach. The only drawback is that browser support is required, and some older browsers may not support cors features.

Cross-domain support is a feature point that should be considered when creating webservice, hopefully this article will help you in this area, using Servicestack to demonstrate cross-domain support, if you use WCF, you know the cross-domain principle, it should be easy to implement cross-domain.

Resources:

Https://github.com/ServiceStack/ServiceStack/wiki/Customize-HTTP-Responses

Https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters

Http://stackoverflow.com/questions/8211930/servicestack-rest-api-and-cors

Http://stackoverflow.com/questions/15224038/rename-callback-parameter-for-jsonp

On cross-domain support of cross-domain with WebService

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.