##Access-Control-Allow-Origin
Access-Control- The Allow-Origin header carries the allowed cross-domain request domain name after server-side verification, which can be a specific domain name or an * (indicating any domain name). |
|
Access-Control-Expose-Headers
The Access-Control-Expose-Headers header is used to allow response headers to be returned to cross-domain requests List, the content of the response header in the list can be accessed by the browser. |
|
Access-Control-Max-Age
Access-Control-Max-Age is used to tell the browser that the result of the pre-check request can be returned Cache time. During the cache validity period, the browser will use the cached pre-check results to determine whether to send a cross-domain request. |
|
Access-Control-Allow-Methods
Access-Control-Allow-Methods is used to tell the browser that it can actually send cross-domain requests , the supported request methods can be a specific method list or an * (indicating any method). |
|
How to use
The client only needs to set the request header according to the specification.
The server identifies and returns the corresponding response header according to the specification, or installs the corresponding plug-in, modifies the corresponding framework configuration file, etc. It depends on the language and framework used by the server
SpringBoot CORS setting example
A piece of code about CORS configuration in a spring boot project
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String temp = request.getHeader("Origin");
httpServletResponse.setHeader("Access-Control-Allow-Origin", temp);
// 允许的访问方法
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
// Access-Control-Max-Age 用于 CORS 相关配置的缓存
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
httpServletResponse.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept,token");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
JSONP Cross-domain
The principle of jsonp is to use the <script> tag in HTML to introduce resources across domains. Therefore, a <srcipt> tag is dynamically created, and src is the function name of the destination interface get data packet to process data. After receiving the GET request, the backend parses and returns the function name (data) to the front end. The front end<script> tag dynamically executes the processing function<br/>Observe the following code</script>
Front-end code
nbsp;html>
<meta>
<title>Title</title>
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为getData
script.src = 'http://localhost:8080/users?username=xbc&callback=handleData';
document.body.appendChild(script);
// 回调执行函数
function handleData(res) {
data = JSON.stringify(res)
console.log(data);
}
</script>
Backend Code (nodejs)
var querystring = require('querystring');
var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
var params = querystring.parse(req.url.split('?')[1]);
var fn = params.callback;
// jsonp返回设置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
var data = {
user: 'xbc',
password: '123456'
}
res.write(fn + '(' + JSON.stringify(data) + ')');
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
In this example, the res received by the front desk is like this
The front-end page is like this
##Note
Since JSONP uses , then it can only Supports GET requests. Other requests cannot be implementednginx reverse proxy realizes cross-domain
Ideas
Since the browser has same-origin policy restrictions, then we put the front-end project Isn’t it enough to put the api interface address requested by the front end under the same origin? Combined with the reverse proxy provided by the web server, cross-domain problems can be solved without any configuration on the front end or back end. Take nginx as an exampleThe real background address of the backend: http://xxx.xxx.xxx.xxx:8085 The background address uses the spring boot project deployed by tomcat Named
gsms_test
nginx server address: http://xxx.xxx.xxx.xxx:8082
Both tomcat and nginx are used Set up by docker and do port forwardingConditions of use: The development environment is a linux systemnginx /etc/nginx/conf.d/default.confThe configuration code is as follows
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# root /usr/share/nginx/html/dist; # 前端项目路径
# index index.html index.htm;
proxy_pass http://localhost:8001/; # 前端本机地址,实现自动更新
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
}
location /gsms_test/ {
proxy_pass 后端真实地址;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
Pages in different domains communicate across domains
window.name iframe cross-domain
window.name is browsing The data shared by a window in the server will still exist after loading in different pages (or even different domain names) (the value will not change if it is not modified), and can support very long
name value (2MB). for example
If a page in domain a wants to obtain data from a page in domain b, you can modify the window.name value in domain b. Switch domain a to domain b and switch back again to get the window.name value of domain b. But we definitely don’t want to switch pages back and forth during development, so we have to combine iframe to achieve it.
Example (implemented with thinkjs)
a The domain code is as follows
nbsp;html>
<meta>
<title>A 域</title>
<h1>server A</h1>
<script>
function getData() {
var iframe = document.getElementById('proxy');
iframe.onload = function () {
var name = iframe.contentWindow.name; // 获取iframe窗口里的window.name值
console.log(name)
}
// 由于iframe信息传递也受同源策略限制,所以在window.name被B域修改后,将iframe转回A域下。以便获取iframe的window.name值
iframe.src = 'http://127.0.0.1:8360/sub.html'
}
</script>
<iframe> </iframe>
b The domain code
nbsp;html>
<meta>
<title>New ThinkJS Application</title>
<h1>server 2</h1>
<script>
window.name = 'user: xbc';
</script>
Note Due to the restriction of the same-origin policy, the parent page obtains incomplete information from the cross-domain iframe page. Therefore, after the window.name of the iframe is modified by the B domain, it must be converted to any page under the A domain. (Window.name must not be modified on this side) and is being obtained. Proxy page iframe realizes cross-domain accessSince mutual access between iframe and parent page is also restricted by the same-origin policy, a proxy page is needed to achieve cross-domain access.
I personally think it is a bit troublesome. If you are interested, please see how the front-end uses a proxy page to solve the problem of iframe cross-domain access?
Summary
The above are all cross-domain methods that I have used or tested. There are also cross-domain methods such as postMessage and WebSocket because I have never Contact without explanation. Which methods should be specifically used in the project also need to consider various issues
Situation | Method |
Only GET request | JSONP |
No requirements for compatibility and browser version | CORS |
Requirements for compatibility and browser version | iframe or server reverse proxy (developed in Linux environment) |