Objective
From the beginning of contact with the front-end development, 跨域
the word has been at a very high frequency at the side of repeated, until now, has been debugging N cross-domain related issues, 16 also collated a related article, but the feeling is still poor point what, so now re-comb a bit.
Personal Insight Limited, if there is a mistake, please forgive me, welcome to put forward issue, see this title, do not spray ~
Outline
About cross-domain, there are n types, this article only focus on ajax请求跨域
(, Ajax cross-domain is only part of the browser "same-Origin policy", the other is also a cookie cross-domain iframe cross-domain, Localstorage cross-domain, etc.), the content is probably as follows:
What is Ajax cross-domain
- Principle
- Performance (sorting out some of the problems encountered and solutions)
How to troubleshoot Ajax cross-domain
- Jsonp Way
- Cors mode
- Proxy Request method
How to analyze Ajax cross-domain
- Analysis of HTTP packet capture
- Some examples
What is the principle of Ajax cross-domain ajax across domains
Ajax requests cross-domain error problem, the main reason is because the browser "homologous policy", you can refer to
Browser homology policy and its avoidance method (Nanyi)
Cors Request principle
Cors is a universal standard, with the name "cross-domain resource sharing" (cross-origin resource sharing). It allows the browser to issue XMLHttpRequest requests to cross-origin servers, overcoming the limitation that Ajax can only use the same origin.
Basically all browsers now implement the Cors standard, in fact, almost all of the browser Ajax requests are based on the cors mechanism, but it is possible that the front-end developers do not care about it (so that its implementation in the Cors solution is mainly to consider how the background to implement the problem).
For Cors, it is highly recommended to read
Cross-domain resource sharing CORS detailed (Nanyi)
In addition, an implementation schematic (simplified version) is also organized here:
How can I tell if it is a simple request?
The browser divides the Cors requests into two categories: simple request and non-simple (Not-so-simple request). As long as the following two conditions are met, it is a simple request.
It is a non-simple request that does not satisfy the above two conditions at the same time.
The performance of the Ajax cross-domain
To tell the truth, I had an article, and then as a solution, but later found that there are still many people still do not. Helpless only time-consuming and laborious debugging. However, even if I analyze it, it is important to judge whether it is cross-domain based on the corresponding performance.
Ajax requests, if there is a cross-domain phenomenon, and is not resolved, there will be the following: (Note that is the AJAX request, please do not say why the HTTP request can, and Ajax does not, because Ajax is accompanied by the cross-domain, so just HTTP request OK is not possible)
Note: For the specific backend cross-domain configuration, please see the topic location.
The first of these phenomena:
No ‘Access-Control-Allow-Origin‘ header is present on the requested resource
And
The response had HTTP status code 404
This situation occurs for the following reasons:
- This AJAX request is a "non-trivial request", so a pre-check request (OPTIONS) is sent before the request
- The server-side background interface does not allow the options request, resulting in the inability to find the corresponding interface address
Solution: Back-end allow options requests
The second phenomenon:
No ‘Access-Control-Allow-Origin‘ header is present on the requested resource
And
The response had HTTP status code 405
This behavior differs from the first, in which case the background method allows the options request, but some configuration files (such as 安全配置
) block the options request, which can cause this behavior
Solution: The backend shuts down the corresponding security configuration
The third phenomenon:
No ‘Access-Control-Allow-Origin‘ header is present on the requested resource
And
status 200
This behavior differs from the first and second, in which case the server-side background allows the options request, and the interface allows the options request, but there is a mismatch in the head match
For example, Origin header check mismatch, such as the lack of some head support (such as the Common X-requested-with head), then the server will return response to the front end, the front end detects this trigger Xhr.onerror, leading to the front console error
Solution: Back end adds corresponding head support
The fourth kind of phenomenon:
heade contains multiple values ‘*,*‘
The behavior is that there are two HTTP header messages for the background responseAccess-Control-Allow-Origin:*
To be honest, the main reason for this problem is that people who cross-domain configuration do not understand the principle, resulting in duplicate configuration, such as:
- Common in. NET background (typically an origin is configured in Web. config, and then the origin is added manually in the code (for example, the code manually sets the return *))
- Common in. NET background (set origin:* in both IIS and Project Webconfig)
Solution (one by one corresponds):
- It is recommended to remove the code from the manually added *, only in the project configuration
- It is recommended that you remove the configuration under IIS *, only in the project configuration
How to troubleshoot Ajax cross-domain
The general Ajax cross-domain solution is resolved by JSONP or cors, such as the following: (note that now almost no longer use JSONP, so Jsonp understand the next can)
Jsonp Way to solve cross-domain problems
Jsonp solving cross-domain issues is a relatively ancient scenario (not recommended in practice), here is a brief introduction (in real-world projects if you want to use JSONP, you will typically use the JQ and other JSONP-encapsulated class libraries to make AJAX requests)
Implementation principle
Jsonp is able to solve cross-domain scenarios primarily because <script> scripts have cross-domain capabilities, and Jsonp is leveraging this. Specific principles
Implementation process
The implementation steps of JSONP are as follows (refer to the articles in the source)
Client page Web pages request JSON data from the server by adding a <script> element that is not restricted by the same-origin policy
functionAddscripttag (src) {var script = document.createelement ( "type", "Text/javascript"); script.src = Src document.body.appendchild (script);} window.onload = function ( Span class= "Hljs-params") {Addscripttag ( ' Http://example.com/ip?callback=foo ');} function foo ( data) {console.log ( ' response data: ' + json.stringify (data);};
When requested, the interface address is the SRC of the built-in script tag, so that when the script tag is built, the final SRC is the content returned by the interface
- The interface corresponding to the server adds a function wrapping layer outside the return parameter
foo({ "test": "testData"});
- Because of the script requested by the <script> element, it runs directly as code. At this point, as soon as the browser defines the Foo function, the function is called immediately. JSON data as a parameter is treated as a JavaScript object, not as a string, so the steps to use Json.parse are avoided.
Note that the general JSONP interface and normal interface return data is different, so if the interface to do jsono compatibility, need to determine if there is a corresponding callback keyword parameters, if there is a JSONP request, return JSONP data, otherwise return normal data
Use note
Based on the implementation principle of JSONP, so JSONP can only be "GET" request, not more complex post and other requests, so in that case, you have to refer to the following Cors resolution cross-domain (so now it is basically eliminated)
Cors solves cross-domain issues
The principle of cors is described above, and the main thing here is how the backend should be configured to solve the problem in the actual project (since a lot of project practices are addressed by the backend), here are some common back-end solutions:
PHP Background Configuration
PHP backend configuration is almost all the simplest in the background, follow the following steps:
- First step: Configure PHP Background to allow cross-domain
<?phpheader(‘Access-Control-Allow-Origin: *‘);header(‘Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept‘);//主要为跨域CORS配置的两大基本信息,Origin和headers
- Step Two: Configure the Apache Web server Across domains (httpd.conf)
Original code
<Directory /> AllowOverride none Require all denied</Directory>
Change to the following code
<Directory /> Options FollowSymLinks AllowOverride none Order deny,allow Allow from all</Directory>
node. JS background configuration (Express framework)
The backend of node. JS is also relatively simple to configure. Simply configure with Express as follows:
App.all (‘*‘,functionreq, Res, next) {Res.header ( "Access-control-allow-origin", "*"); Res.header ( "Access-control-allow-headers", "X-requested-with"); Res.header ( "Access-control-allow-methods", "PUT,POST,GET, Delete,options "); Res.header ( "x-powered-by", ' 3.2.1 ') //This paragraph is just for the convenience of returning JSON Res.header ( "Content-type", " Application/json;charset=utf-8 "); if (Req.method = ' OPTIONS ') {// Quickly return the options request to Res.sendstatus (200);} else {next ();}});
Java Background configuration
Java background configuration only needs to follow the following steps:
<dependency> <groupId>com.thetransactioncompany</groupId> <artifactId>cors-filter</artifactId> <version>[ version ]</version></dependency>
Where the version should be the latest stable version, Cors filter
- Step three: Add Cors configuration to the project's Web. XML (App/web-inf/web.xml)
<!--cross-domain configuration-<Filter><!--the CORS filter with parameters--<Filter-name>cors</Filter-name><Filter-class>com.thetransactioncompany.cors.corsfilter</Filter-class><!--Note:all parameters is options, if omitted the CORS Filter would fall back to the respective default values. -<Init-param><Param-name>cors.allowgenerichttprequests</Param-name><Param-value>true</Param-value></Init-param><Init-param><Param-name>cors.alloworigin</Param-name><param-value>*</Param-value></Init-param><Init-param><Param-name>cors.allowsubdomains</Param-name><Param-value>false</Param-value></Init-param><Init-param><Param-name>cors.supportedmethods</Param-name><Param-value>get, HEAD, POST, OPTIONS</Param-value></Init-param><Init-param><Param-name>cors.supportedheaders</Param-name><Param-value>accept, Origin, X-requested-with, Content-type, last-modified</Param-value></Init-param><Init-param><Param-name>cors.exposedheaders</Param-name><!--Here you can add some of your own exposure headers---<Param-value>x-test-1, X-test-2</Param-value></Init-param><Init-param><Param-name>cors.supportscredentials</Param-name><Param-value>true</Param-value></Init-param><Init-param><Param-name>cors.maxage</param-name> < param-value>3600</param-value> </init-param> </ filter> <filter-mapping> <!--CORS Filter Mapping-to < Filter-name>cors</filter-name> <url-pattern>/*</url-pattern > </FILTER-MAPPING>
Please note that the above configuration file is placed in front of the Web. XML, as the first filter exists (can have multiple filter)
- Fourth step: Possible Security Module Configuration error (note that some frameworks-such as the company's private framework, there are security modules, sometimes these security module configuration will affect cross-domain configuration, you can first try to close them)
JAVA Spring Boot Configuration
20171230 Supplement
Simply list the simple global configuration
@Configurationpublic class corsconfig {private corsconfiguration buildconfig () {corsconfiguration CorsConfigurat Ion = new corsconfiguration (); //can self-filter corsconfiguration.addallowedorigin ( "*"); Corsconfiguration.addallowedheader ( "*"); Corsconfiguration.addallowedmethod (return corsconfiguration;} @Bean public Corsfilter Corsfilter () {Urlbasedcorsconfigurationsource Source = new Urlbasedcorsconfigurationsource (); Source.registercorsconfiguration ( "/**", Buildconfig ()); return new corsfilter (source);}}
Create a new configuration, then add a configuration note to configure the success
PS: This part of the method is included, no hands-on practice, but according to feedback, theoretically feasible
NET Background configuration
. NET background configuration can refer to the following steps:
- First Step: Site Configuration
Open the Control Panel, select Administrative Tools, select IIS, right-click your Web site, select Browse, open the directory where the Web site is located, open the Web. config file with Notepad, add the following configuration information, restart the site
Please note that older, if the configuration still problems, you can consider adding more headers allow, such as:
"Access-Control-Allow-Headers":"X-Requested-With,Content-Type,Accept,Origin"
Second Step: Additional configuration, if the first step has been done, there are still cross-domain issues, may be:
- The interface has some restrictions on the number of dead request types (such as writing dead post, etc.), please remove the limit
- Interface, the configuration is repeated
Origin:*
, please remove the
- IIS server, the configuration is repeated
Origin:*
, please remove the
Proxy request method resolves interface cross-domain issues
Note that because the interface agent is at a cost, this is only done during the development process.
Unlike the previous method, the front cors is the backend solution, and this is mainly the front end of the interface agent, that is:
- The front-end AJAX request is local interface
- The local interface requests data to the actual interface after it receives the request, and then returns the information to the front end
- Typically use node. js to Proxy
about how to implement the agent, here is not the focus of description, methods and many, it is not difficult, basically is based on node. js.
Search for keywords node.js
to 代理请求
find a big package.
Optimization of options Pre-test
Access-Control-Max-Age:
The number of seconds the request can be cached after this header is added.
In this timeframe, all requests of the same type will no longer send a preflight request and use the returned header directly as a basis for judgment.
Very useful, can greatly optimize the number of requests
How to analyze Ajax cross-domain
The above has introduced the principle of cross-domain and how to solve, but in the actual process, found that there are still many people to follow similar documents can not solve cross-domain problems, mainly reflected in, the front-end personnel do not know when the cross-domain problem caused, when not, so here is a little introduction to how to analyze a request cross-domain:
Grab Packet Request data
The first step, of course, is to know what data our AJAX requests are sending, what we receive, and it's not difficult to do this, or to fiddler
wait for tools, based on just Chrome
Chrome
The browser opens a page that corresponds to an AJAX occurrence, F12
opensDev Tools
- Send an AJAX request
- Right panel
NetWork
, and XHR
then find the AJAX request that you just went to.
Example one (normal Ajax request)
The above request is a correct request, for convenience, I put the meaning of each head field is indicated, we can clearly see that the interface returned by the response header field, including the
Access-Control-Allow-Headers: X-Requested-With,Content-Type,AcceptAccess-Control-Allow-Methods: Get,Post,Put,OPTIONSAccess-Control-Allow-Origin: *
Therefore, when the browser receives the response, the correct request is judged, and the response data is successfully obtained.
Example two (cross-domain error AJAX request)
For convenience, we still take an example of the error shown above.
In this request, the interface allow is not included OPTIONS
, so the request appears across the domain,
This request, which Access-Control-Allow-Origin: *
occurred two times, caused the cross-domain configuration to not be configured correctly and an error occurred.
More cross-domain errors are basically similar, that is, the above three is not satisfied (Headers,allow,origin), here no longer one by one repeat.
Example three (Ajax requests that are cross-domain independent)
Of course, not all Ajax request errors are related to cross-domain, so please do not confuse, such as the following:
For example, this request, its cross-domain configuration is not a bit of a problem, it is only because of request Accept
and response mismatch Content-Type
.
More
Basically this is the analysis of an AJAX request, through the Chrome
can know what data sent, what data received, and then the right to know what the problem is.
Written in the last words
Cross-domain is a commonplace topic, there are a lot of cross-domain information on the Internet, and there are a lot of fine products (such as Nanyi predecessors), but as a front-end personnel should not be tasted, and therefore only this article.
Long Front road, hope and gentlemen mutual encouragement!
Appendix Reference
- Browser homology policy and its avoidance method (Nanyi)
- Cross-domain resource sharing CORS detailed (Nanyi)
- My previous article on the Cnblog
Blog
First published 2017.03.22
in a personal blog
- Http://www.dailichun.com/2017/03/22/ajaxCrossDomainSolution.html
Ajax cross-domain, this should be the most complete solution