1谐檀、什么是跨越抡谐?
一個(gè)網(wǎng)頁向另一個(gè)不同域名/不同協(xié)議/不同端口的網(wǎng)頁請(qǐng)求資源,這就是跨域桐猬。
跨域原因產(chǎn)生:在當(dāng)前域名請(qǐng)求網(wǎng)站中童叠,默認(rèn)不允許通過ajax
請(qǐng)求發(fā)送其他域名。
2课幕、為什么會(huì)產(chǎn)生跨域請(qǐng)求厦坛?
因?yàn)闉g覽器使用了同源策略
3、什么是同源策略乍惊?
同源策略是
Netscape
提出的一個(gè)著名的安全策略杜秸,現(xiàn)在所有支持JavaScript
的瀏覽器都會(huì)使用這個(gè)策略。同源策略是瀏覽器最核心也最基本的安全功能润绎,如果缺少同源策略撬碟,瀏覽器的正常功能可能受到影響±蚱玻可以說web
是構(gòu)建在同源策略的基礎(chǔ)之上的呢蛤,瀏覽器只是針對(duì)同源策略的一種實(shí)現(xiàn)。
4棍郎、為什么瀏覽器要使用同源策略其障?
是為了保證用戶的信息安全,防止惡意網(wǎng)站竊取數(shù)據(jù)涂佃,如果網(wǎng)頁之間不滿足同源要求励翼,將不能:
- 1、共享Cookie辜荠、LocalStorage汽抚、IndexDB
- 2、獲取DOM
- 3伯病、AJAX請(qǐng)求不能發(fā)送
同源策略的非絕對(duì)性:
<script></script>
<img/>
<iframe/>
<link/>
<video/>
<audio/>
等帶有
src
屬性的標(biāo)簽可以從不同的域加載和執(zhí)行資源造烁。其他插件的同源策略:flash
、java applet
、silverlight
惭蟋、googlegears
等瀏覽器加載的第三方插件也有各自的同源策略叠纹,只是這些同源策略不屬于瀏覽器原生的同源策略,如果有漏洞則可能被黑客利用敞葛,從而留下XSS
攻擊的后患
所謂的同源指:
域名誉察、網(wǎng)絡(luò)協(xié)議、端口號(hào)相同惹谐,三條有一條不同就會(huì)產(chǎn)生跨域持偏。 例如:你用瀏覽器打開http://baidu.com,瀏覽器執(zhí)行JavaScript腳本時(shí)發(fā)現(xiàn)腳本向http://cloud.baidu.com域名發(fā)請(qǐng)求氨肌,這時(shí)瀏覽器就會(huì)報(bào)錯(cuò)鸿秆,這就是跨域報(bào)錯(cuò)。
解決方案有五:
1怎囚、前端使用jsonp (不推薦使用)
當(dāng)我們正常地請(qǐng)求一個(gè)
JSON
數(shù)據(jù)的時(shí)候卿叽,服務(wù)端返回的是一串JSON
類型的數(shù)據(jù),而我們使用JSONP
模式來請(qǐng)求數(shù)據(jù)的時(shí)候服務(wù)端返回的是一段可執(zhí)行的JavaScript
代碼恳守。因?yàn)?code>jsonp 跨域的原理就是用的動(dòng)態(tài)加載script
的src
考婴,所以我們只能把參數(shù)通過url
的方式傳遞,所以jsonp
的type
類型只能是get
示例:
$.ajax({
url: 'http://192.168.1.114/yii/demos/test.php', //不同的域
type: 'GET', // jsonp模式只有GET 是合法的
data: {
'action': 'aaron'
},
dataType: 'jsonp', // 數(shù)據(jù)類型
jsonp: 'backfunc', // 指定回調(diào)函數(shù)名,與服務(wù)器端接收的一致催烘,并回傳回來
})
使用
JSONP
模式來請(qǐng)求數(shù)據(jù)的整個(gè)流程:
客戶端發(fā)送一個(gè)請(qǐng)求沥阱,規(guī)定一個(gè)可執(zhí)行的函數(shù)名(這里就是jQuery
做了封裝的處理,自動(dòng)幫你生成回調(diào)函數(shù)并把數(shù)據(jù)取出來供success
屬性方法來調(diào)用,而不是傳遞的一個(gè)回調(diào)句柄)伊群,服務(wù)器端接受了這個(gè)backfunc
函數(shù)名考杉,然后把數(shù)據(jù)通過實(shí)參的形式發(fā)送出去
(在
jquery
源碼中,jsonp
的實(shí)現(xiàn)方式是動(dòng)態(tài)添加<script>
標(biāo)簽來調(diào)用服務(wù)器提供的js
腳本舰始。jquery
會(huì)在window
對(duì)象中加載一個(gè)全局的函數(shù)崇棠,當(dāng)<script>
代碼插入時(shí)函數(shù)執(zhí)行,執(zhí)行完畢后就<script>
會(huì)被移除丸卷。同時(shí)jquery
還對(duì)非跨域的請(qǐng)求進(jìn)行了優(yōu)化枕稀,如果這個(gè)請(qǐng)求是在同一個(gè)域名下那么他就會(huì)像正常的Ajax
請(qǐng)求一樣工作。)
2及老、后臺(tái) Http 請(qǐng)求轉(zhuǎn)發(fā)
使用HttpClinet
轉(zhuǎn)發(fā)進(jìn)行轉(zhuǎn)發(fā)(簡(jiǎn)單的例子 不推薦使用這種方式)
try {
HttpClient client = HttpClients.createDefault(); //client對(duì)象
HttpGet get = new HttpGet("http://localhost:8080/test"); //創(chuàng)建get請(qǐng)求
CloseableHttpResponse response = httpClient.execute(get); //執(zhí)行g(shù)et請(qǐng)求
String mes = EntityUtils.toString(response.getEntity()); //將返回體的信息轉(zhuǎn)換為字符串
System.out.println(mes);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
3抽莱、后臺(tái)配置同源Cors (推薦)
在
SpringBoot2.0
上的跨域 用以下代碼配置 即可完美解決你的前后端跨域請(qǐng)求問題
在SpringBoot2.0
上的跨域 用以下代碼配置 即可完美解決你的前后端跨域請(qǐng)求問題
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 實(shí)現(xiàn)基本的跨域請(qǐng)求
* @author linhongcun
*
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/*是否允許請(qǐng)求帶有驗(yàn)證信息*/
corsConfiguration.setAllowCredentials(true);
/*允許訪問的客戶端域名*/
corsConfiguration.addAllowedOrigin("*");
/*允許服務(wù)端訪問的客戶端請(qǐng)求頭*/
corsConfiguration.addAllowedHeader("*");
/*允許訪問的方法名,GET POST等*/
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
4、使用 SpringCloud 網(wǎng)關(guān)
服務(wù)網(wǎng)關(guān)
(zuul)
又稱路由中心骄恶,用來統(tǒng)一訪問所有api
接口,維護(hù)服務(wù)匕垫。
Spring Cloud Zuul
通過與Spring Cloud Eureka
的整合僧鲁,實(shí)現(xiàn)了對(duì)服務(wù)實(shí)例的自動(dòng)化維護(hù),所以在使用服務(wù)路由配置的時(shí)候,我們不需要向傳統(tǒng)路由配置方式那樣去指定具體的服務(wù)實(shí)例地址寞秃,只需要通過Ant
模式配置文件參數(shù)即可
5斟叼、使用 nginx 做轉(zhuǎn)發(fā)
現(xiàn)在有兩個(gè)網(wǎng)站想互相訪問接口 在http://a.a.com:81/A中想訪問 http://b.b.com:81/B 那么進(jìn)行如下配置即可
然后通過訪問 www.my.com/A 里面即可訪問 www.my.com/B
server {
listen 80;
server_name www.my.com;
location /A {
proxy_pass http://a.a.com:81/A;
index index.html index.htm;
}
location /B {
proxy_pass http://b.b.com:81/B;
index index.html index.htm;
}
}
如果是兩個(gè)端口想互相訪問接口 在http://b.b.com:80/Api中想訪問 http://b.b.com:81/Api 那么進(jìn)行如下配置即可
使用nginx轉(zhuǎn)發(fā)機(jī)制就可以完成跨域問題
server {
listen 80;
server_name b.b.com;
location /Api {
proxy_pass http://b.b.com:81/Api;
index index.html index.htm;
}
}