JS cross-domain problem

Source: Internet
Author: User
Tags array definition epoll domain server

How to solve JS cross-domain problem

JS cross-domain problem is one of the most common problems that web developers encounter. The so-called JS cross-domain problem, refers to the page under one domain through the JS access to another different domain data objects, for security reasons, almost all browsers do not allow this cross-domain access, which leads to some AJAX applications, the use of cross-domain Web service becomes a problem. To solve the JS cross-domain problem, there are some ready-made solutions on both the client and the server side, but these solutions will not solve all problems. Let's take a look at some common solutions, and provide a space-based solution to the demand for cross-domain issues, hoping to be useful to other product groups.

Client Solutions

How to solve the JS cross-domain problem on the client is almost all the Web developers will consider first. Currently, there are 2 ways to do this: set Document.domain, load through script tags.

Set Document.domain

The premise of this approach is that the two pages involved in cross-domain requests must belong to one base domain (for example, xxx.com, or xxx.com.cn), using the same protocol (for example, HTTP) and the same port (for example, 80). For example, a page inside a aaa.xxx.com needs to call an object in Bbb.xxx.com, and the document.domain of the two pages is set to xxx.com, which enables cross-domain invocation. In addition, it should be noted that this method can only be used in the parent, child pages, that is, only when the data access with the IFRAME is used.

Load by script tag

For a browser, the SRC attribute of the script tag is the same as the resource pointed to by the SRC attribute of the IMG tag, which is a static resource, and the browser automatically loads the resources at the appropriate time without the so-called cross-domain problem. This allows us to bypass the JS cross-domain problem by referencing the data object that the property will be accessing into the current page. For example, in the space of my spatial project, I need to randomly recommend several popular modules to the user in the Hi Domain Admin Center page, because the relevant information of the popular modules is maintained in the PHP module under the ACT domain, JS cross-domain problem occurs if you are directly under the HI domain to get information about the recommended modules list under the ACT domain via AJAX requests. The simplest way to solve this problem is to access the HTTP interface provided by the ACT domain under the HI domain via the script tag:

<script type= "Text/javascript" src= "Http://act.hi.baidu.com/widget/recommend" ><script>


Of course, the premise is that this HTTP interface of the ACT domain must be a script that returns a JS script, such as a JSON object array definition:

Modlist = [{"ModName": "Mod1",  "Usernum": $, "url": "/widget/info/1"},{"ModName": "Mod2",  "Usernum": 300, "url": "/WIDGET/INFO/2"},...];


But the script tag also has some limitations, and does not solve all the JS cross-domain problems. The SRC attribute value of the script tag cannot be dynamically changed to meet the need to obtain different data under different conditions, and more importantly, data organized in XML content cannot be properly accessed in this way.

Service-Side Solutions

As you can see from the instructions above, the client's solution is too restrictive, and for Ajax cross-domain requests, no matter whether the two domains belong to the same base domain, they cannot be resolved on the client. That is, if we want to access the data under other domains in an AJAX request, we can only process it through the server. The basic principle of a service-side solution is that the client sends the request to the local domain server, and then the proxy of the domain server requests the data and returns the response to the client. The most common server solution is to take advantage of the proxy functionality provided by the Web server itself, such as the Mod_proxy module for Apache and LIGHTTPD. Inside Baidu, transmit's shunt function can also solve partial cross-domain problem. However, these methods have certain limitations, in view of security issues such as consideration, space this end developed a dedicated to the cross-domain request Proxy service Spproxy module, for the complete solution of JS cross-domain problem. Below we will take the space open platform as an example, briefly introduce how to solve the cross-domain problem through Apache mod_proxy, transmit and Space Spproxy module, and briefly introduce some features, shortcomings and next improvement plan of Spproxy. Space before each UWA open module must request the module's XML source code to parse, each module of source files are stored in the ACT domain under the/ow/uwa directory, then in the User space home (HI domain) request the XML file there will be a JS cross-domain problem. To resolve this problem, only JS requests the XML file to the HI domain's Web server, while the HI Domain Web server requests the file to the ACT domain's Web server through a certain proxy mechanism (such as mod_proxy, transmit shunt, spproxy).

Using Apache's Mod_proxy module

If Apache is a 2.0-series version, it can be resolved by adding the following configuration to the httpd.conf file:

Proxyrequests  off<proxy *>order deny,allowallow from All</proxy>proxypass  /ow/uwa/  http Act.hi.baidu.com/ow/uwa


Where the proxyrequests directive turns off the forward proxy feature of Mod_proxy and enables the reverse proxy function, the proxy directive makes the configuration effective for all accesses, and the proxypass instruction makes the/ow/ Access to any resource under the UWA directory is internally converted to a proxy request for the corresponding resource under the/ow/uwa directory under the act.hi.baidu.com domain. In this way, JS can get the 10001.xml file in the/ow/uwa/0/1/0/directory under the ACT domain directly by accessing http://hi.baidu.com/ow/uwa/0/1/0/10001.xml.

If Apache has been modified by the Baidu product line 1.3 version, you need to mod_proxy and mod_rewrite modules together to achieve the same purpose. You first need to add the following location directives to the httpd.conf:

<location/ow/uwa>sethandler Proxy-serverorder Allow,denyallow from all</location>


Thus, access to any of the resources under the/ow/uwa directory under this domain will first be handled by the Proxy-server handler (a handler defined inside the Mod_proxy module), but this configuration is not yet available. Because not proxy-server still do not know how to deal with, just know need to deal with their own. You also need to add a rewrite rule in the configuration section:

Rewriterule ^/ow/uwa/(. *) $  http://act.hi.baidu.com/ow/uwa/$1?%{query_string} [p,l]


The last [p,l] of the rewrite rule indicates that the rewrite was passed through the Mod_proxy proxy, rather than through an external redirect. If the P flag is removed, the following rewrite rule is used:

Rewriterule ^/ow/uwa/(. *) $  http://act.hi.baidu.com/ow/uwa/$1?%{query_string} [L]


The resource URI indicated when the response is returned to the client will be the redirected URI, which in our case is the URI of the act.hi.baidu.com domain, and the browser will still have a JS cross-domain problem. The above is only a simple application of the proxy function of Apache, a better and more powerful introduction can be reference to "1" and "2". Mod_proxy is powerful, but we don't use it to solve cross-domain problems. First of all, to use it must require that each of our front-end machine can access the extranet, or we can only proxy the request to one of the front-end machines (through the machine name to do the intranet domain name for rewrite or proxy), and this is obviously undesirable, because one of our domain name is usually composed of many front-end machines, Only agent to one of the machines will cause the machine pressure compared to other machines is very uneven, even can not withstand the pressure, and to all front-end machines have access to the network permissions and there may be some security policy issues (the specific reasons are unclear, but op and SA obviously will not endorse this practice). Second, because Apache itself does not have a good anti-DDoS attack mechanism, once someone through the proxy to attack the target domain (for example, our competitor's website), in the target domain of the Web server, it appears that the attacker is us, such things happen, we moments, Jumping into the Yellow River is also not clear.

Using transmit shunt scheme

Used transmit product line should know, transmit in addition to anti-attack, there is a very important function is shunt. With the shunt feature, we can distribute access to specific URLs to different Apache processing for cross-domain access purposes. As an example of a space-open platform, let's say that our act domain consists of two machines, JX-SPACE-ACT00.JX and JX-SPACE-ACT01.JX, in the JX room, with Apache port 8080, As long as we add the following configuration in transmit configuration file transmit_common.conf:

Pp_apache_dir    :   /ow/uwa/pp_apache0      :   jx-space-act00.jx:8080pp_apache1      :   jx-space-act01.jx:8080


After restarting transmit, the Southern user can access the Http://hi.baidu.com/ow/uwa/0/1/0/10001.xml and get the http://act.hi.baidu.com/ow/uwa/0/1/0/ 10001.xml the XML content executed by this URL to resolve cross-domain issues. If we are in the HI domain and want to get other data from the act domain asynchronously, such as the data provided by the/sys/widget/xxx interface, you only need to add a directory definition to the PP_APACHE_DIR configuration item:

Pp_apache_dir    :   /ow/uwa/,/sys/widget/


Since older versions of transmit only support a single shunt, it is not possible to resolve cross-domain requests to multiple domains at the same time, and to support older versions of transmit, the backend Apache needs to do the appropriate code modification and configuration. This also restricts our shunt function to solve cross-domain problems across non-Baidu domains. However, the good news is that the new version of GM recently released transmit allows the addition of N shunts, while supporting the back-end Apache does not make any changes, then the old version of the transmit encountered by the restrictions will no longer exist, it can be a good way to solve the cross-domain problem. The specific configuration method is similar to the old version, you can refer to the new version transmit configuration file for the corresponding modification to achieve this purpose.

Using the Spproxy module

However, in Space's open platform system, we do not solve the cross-domain problem through transmit, mentioned earlier, transmit can only solve this problem to some extent. Why do you say that? Since transmit increases the shunt is required to restart the transmit program after configuration modification, and as the branching branch increases, its performance will continue to degrade, after all, each request comes when it needs to traverse all branches to determine which branch to go, and for the Open platform, Any new open module may introduce one or more new fields, which leads to a linear increase in the number of branching branches of the transmit as the number of open modules increases, which is unacceptable both in OP operations and in program performance. Based on this consideration, space has introduced a new module--spproxy module in the open platform two project, which is used to provide cross-domain request Proxy service, which completely solves the JS cross-domain problem. In a sense, Spproxy is actually a UI that receives a request from Apache and processes the request to get the real page data, which is then returned to Apache and returned by Apache to the client. The spproxy receives only one Apache command number (ac_sys_proxy:38) and provides two HTTP interfaces:

/sys/pxy/ajax?url=xxxx and/sys/pxy/xml?url=xxx


Where/sys/pxy/can be modified through the Apache configuration file to other directory names, url parameter is JS want to cross-domain request data URI (URL encoding, if there are parameters in the URL), XML interface and AJAX interface is the only difference between, Spproxy forces the Content-type of the contents of the former to be set to Text/xml, and for the latter, what type of Content-type is returned by the other server. Apache side only need to add the following two configuration can let spproxy to handle the above two HTTP interface request, of course, if the use of Apache is the NS rewritten Apache, is currently mainly 1.3 version of Apache:

Cmdnomap   pxy      38CmdHost      pxy 20540


Where Pxy is the second directory name in the HTTP interface, can be customized, for example, if the configuration is written in proxy, then the HTTP interface is/sys/proxy/ajax?url=xxx and/sys/proxy/xml?url=xxx ; 38 is the command number that spproxy can handle, which can be modified to other values at compile time, and 20540 is the listening port of the IP and Spproxy of the machine where the Spproxy is located. With the above configuration, JS in the HI domain can be accessed asynchronously via the http://hi.baidu.com/sys/pxy/xml?url=http://act.hi.baidu.com/ow/uwa/0/1/0/10001. XML to access http://act.hi.baidu.com/ow/uwa/0/1/0/10001.xml across domains. If a resource URI with a cross-domain access is a parameter, such as HTTP://ACT.HI.BAIDU.COM/WIDGET/RECOMMEND?NUM=6, the parameter value needs to be URL-encoded when accessed, such as http://hi.baidu.com/sys/ pxy/xml?url=http%3a%2f%2fact%2ehi%2ebaidu%2ecom%2fwidget%2frecommend%3fnum%3d6.

Spproxy Introduction

Spproxy is a single-process module developed based on the Epoll network model, which contains a data grabbing thread and a timed load thread:? Fetch the thread, proxy the cross-domain request, crawl the page content corresponding to the specified URL and return it to the front end, this thread uses the Epoll model to increase the concurrency of request processing? Timed loading of threads, timed loading of domain name whitelists and partially loadable configuration items (such as various timeouts, whether to force specified cache expiration, etc.) Spproxy limit the domain name that JS can access across domains through a domain name to reduce security risks, Need to add a JS to cross-domain access to the field only need to add a line in the Spproxy domain name whitelist file spproxy_domainlist.txt, after 5 minutes (the specific effective time is configurable) will take effect. Thanks to the Epoll network model, the Spproxy itself is well protected against slow-connection attacks, and it has the same powerful anti-attack capabilities as the space UI. In order to reduce requests from external domain servers to increase the responsiveness of cross-domain requests while reducing the risk of foreign servers blocking our proxy services, Spproxy itself has made a relatively simple cache function. If the cache expiration time is specified in the page HTTP header returned by the alien server, Spproxy calculates a reasonable expiration value and caches the page based on the HTTP header's cache expiration time for the page If the cache expiration time is not specified in the HTTP header returned by the other server, or if the cache is not required, Spproxy will still have a short-term cache for the page, and the expiration time can be configured. In addition, for most of the time-out configuration and the domain name whitelist that are involved in the Spproxy module can be reloaded periodically, so as to realize the online service tuning parameters and increasing the trust domain without restarting the service to invalidate the cache. However, Spproxy also has some shortcomings:? The response body returned to Spproxy cannot be compressed, and Spproxy will indicate this in the HTTP header when requesting to the other, increasing the read response time and the bandwidth consumption of the other sites. Spproxy currently only calculates the cache expiration of a page based on the Max-age property in the Cache-control field in the HTTP response header of an extranet server, while the actual The Cache-control field returned by many websites is not max-age to indicate the cache expiration time? Spproxy currently only supports the Get method, does not support other HTTP methods, and Spproxy does not support any size of the other pages, but can be configured to change the maximum amount of page data it can receive next, Spproxy will parse HThe Cache-control field in the TTP response header has been improved to more reasonably control the cache of the Spproxy back page, and the next step is to support cross-domain requests via the POST method to improve security across domain requests.

JS cross-domain issues

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.