标签:body utf-8 link desc control lte public read turn
浏览器对于javascript的同源策略的限制 。
跨域原因 | 示例 |
域名不同 | aaa.com和bbb.com |
域名相同,端口不同 | aaa.com:81和aaa.com:82 |
二级域名不同 | a.aaa.com和b.aaa.com |
协议不同 | http和https |
跨域不一定会有跨域问题。
跨域问题是浏览器对于ajax请求的一种安全限制,因此跨域问题是针对ajax的一种限制,一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。
最早的解决方案,利用script标签可以跨域的原理实现,存在一定的局限性(需要服务的支持,只能发起GET请求)。
利用nginx反向代理把跨域为不跨域,支持各种请求方式。
缺点:需要在nginx进行额外配置,语义不清晰
规范化的跨域请求解决方案,安全可靠。
jsonp方式不支持POST方式跨域请求,就算指定成POST方式,会自动转为GET方式;而后端如果设置成POST方式了,那就请求不了了。
1 $(function(){ 2 var name=‘cc‘; 3 var looks=‘handsome‘; 4 $.ajax({ 5 url: "http://localhost:9090/student", 6 type: "GET", 7 data:{ 8 name:name, 9 looks:looks 10 }, 11 cache:false, 12 dataType: "jsonp", //指定服务器返回的数据类型 13 jsonp:‘theFunction‘,//用以获得jsonp回调函数名的参数名(默认为:callback) 14 15 jsonpCallback: "showData", //指定回调函数名称 16 success: function (data) { 17 console.info("调用success"); } 18 }); 19 })
凡是拥有src这个属性的标签都可以跨域例如<script><img><iframe>。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 7 <script type="text/javascript"> 8 var message = function(data) { 9 alert(data[1].title); 10 }; 11 </script> 12 13 <script type="text/javascript" src="http://web.cn/js/message.js"></script> 14 </head> 15 <body> 16 <div id=‘testdiv‘></div> 17 </body> 18 </html>
1 this.$http.jsonp(‘http://www.aaa.com:8080/login‘, { 2 params: {}, 3 jsonp: ‘onBack‘ 4 }).then((res) => { 5 console.log(res); 6 })
配置Nginx:/nginx-1.18.0/conf/nginx.conf
1 worker_processes 1; 2 3 events { 4 worker_connections 1024; 5 } 6 7 8 http { 9 include mime.types; 10 default_type application/octet-stream; 11 12 sendfile on; 13 keepalive_timeout 65; 14 15 server { 16 listen 80; 17 server_name manage.aaa.com; 18 19 location / { 20 proxy_pass http://127.0.0.1:8001; 21 proxy_connect_timeout 600; 22 proxy_read_timeout 600; 23 } 24 25 location /api { 26 proxy_pass http://127.0.0.1:8002; 27 proxy_connect_timeout 600; 28 proxy_read_timeout 600; 29 } 30 31 error_page 500 502 503 504 /50x.html; 32 location = /50x.html { 33 root html; 34 } 35 } 36 }
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
只要同时满足以下两
大条件,就属于简单请求。
(1)请求方法是以下三种之一:HEAD、GET、POST。
(2)HTTP的头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)。
1 // 白名单(可接受的域),是一个具体域名或者*(代表任意域名),注意:需要携带cookie时不能设置为* 2 Access-Control-Allow-Origin: * 3 // 是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true 4 Access-Control-Allow-Credentials: false 5 Content-Type: text/html; charset=utf-8
要想操作cookie,需要满足3个条件:
不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT。
预检请求:特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
1 OPTIONS /cors HTTP/1.1 2 Origin: http://manage.leyou.com 3 Access-Control-Request-Method: PUT 4 Access-Control-Request-Headers: X-Custom-Header 5 Host: api.leyou.com 6 Accept-Language: en-US 7 Connection: keep-alive 8 User-Agent: Mozilla/5.0...
预检请求的响应(服务的收到预检请求,如果许可跨域,会发出响应):
1 HTTP/1.1 200 OK 2 Date: Mon, 01 Dec 2008 01:15:39 GMT 3 Server: Apache/2.0.61 (Unix) 4 Access-Control-Allow-Origin: http://manage.leyou.com 5 Access-Control-Allow-Credentials: true 6 Access-Control-Allow-Methods: GET, POST, PUT 7 Access-Control-Allow-Headers: X-Custom-Header 8 Access-Control-Max-Age: 1728000 9 Content-Type: text/html; charset=utf-8 10 Content-Encoding: gzip 11 Content-Length: 0 12 Keep-Alive: timeout=2, max=100 13 Connection: Keep-Alive 14 Content-Type: text/plain
除了Access-Control-Allow-Origin和Access-Control-Allow-Credentials以外,这里又额外多出3个头:Access-Control-Allow-Methods(允许访问的方式)、Access-Control-Allow-Headers(允许携带的头)、Access-Control-Max-Age(本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了)。
如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的了。
服务端可以通过拦截器统一实现,不必每次都去进行跨域判定的编写。
事实上,SpringMVC已经帮我们写好了CORS的跨域过滤器:CorsFilter ,内部已经实现了刚才所讲的判定逻辑,我们直接用就好了。
1 package com.test.config; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.web.cors.CorsConfiguration; 6 import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 import org.springframework.web.filter.CorsFilter; 8 9 /** 10 * @Program: test 11 * @Package: com.test.config 12 * @ClassName: CorsConfiguration 13 * @Description: Cors解决跨域问题 14 * @Author: tankang 15 * @Create: 2020-09-08 23:54 16 */ 17 @Configuration 18 public class CorsConfiguration { 19 @Bean 20 public CorsFilter corsFilter(){ 21 // 初始化cors配置对象 22 CorsConfiguration corsConfiguration = new CorsConfiguration(); 23 corsConfiguration.addAllowedOrigin("http://manage.aaa.com");// 允许跨域的域名,如果需要携带cookie,不能写*,*代表允许所有域名 24 corsConfiguration.setAllowCredentials(true);// 允许携带cookie 25 corsConfiguration.addAllowedMethod("*");// *代表所有的请求方法,get/post/put/delete ... 26 corsConfiguration.addAllowedHeader("*");// 允许携带任何头信息 27 // 初始化cors配置源对象 28 UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); 29 urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); 30 // 返回corsFilter实例,参数cors配置源对象 31 return new CorsFilter(urlBasedCorsConfigurationSource); 32 } 33 }
标签:body utf-8 link desc control lte public read turn
原文地址:https://www.cnblogs.com/tankang/p/13636894.html