因為瀏覽器使用了同源策略,所以產生跨域請求。一個網頁向另一個不同域名/不同協議/不同端口的網頁請求資源,這就是跨域。本篇文章提供了5種方式來解決網站跨域,感興趣的朋友可以看看。
1、什么是跨越?
一個網頁向另一個不同域名/不同協議/不同端口的網頁請求資源,這就是跨域。
跨域原因產生:在當前域名請求網站中,默認不允許通過ajax請求發送其他域名。
2、為什么會產生跨域請求?
因為瀏覽器使用了同源策略
3、什么是同源策略?
同源策略是Netscape提出的一個著名的安全策略,現在所有支持JavaScript的瀏覽器都會使用這個策略。同源策略是瀏覽器最核心也最基本的安全功能,如果缺少同源策略,瀏覽器的正常功能可能受到影響。可以說web是構建在同源策略的基礎之上的,瀏覽器只是針對同源策略的一種實現。
4、為什么瀏覽器要使用同源策略?
是為了保證用戶的信息安全,防止惡意網站竊取數據,如果網頁之間不滿足同源要求,將不能:
1、共享Cookie、LocalStorage、IndexDB
2、獲取DOM
3、AJAX請求不能發送
同源策略的非絕對性:
- <script></script>
- <img/>
- <iframe/>
- <link/>
- <video/>
- <audio/>
等帶有src屬性的標簽可以從不同的域加載和執行資源。其他插件的同源策略:flash、java applet、silverlight、googlegears等瀏覽器加載的第三方插件也有各自的同源策略,只是這些同源策略不屬于瀏覽器原生的同源策略,如果有漏洞則可能被黑客利用,從而留下XSS攻擊的后患
所謂的同源指:域名、網絡協議、端口號相同,三條有一條不同就會產生跨域。 例如:你用瀏覽器打開http://baidu.com,瀏覽器執行JavaScript腳本時發現腳本向http://cloud.baidu.com域名發請求,這時瀏覽器就會報錯,這就是跨域報錯。
解決方案有五:
1、前端使用jsonp (不推薦使用)
當我們正常地請求一個JSON數據的時候,服務端返回的是一串 JSON類型的數據,而我們使用 JSONP模式來請求數據的時候服務端返回的是一段可執行的 JavaScript代碼。因為jsonp 跨域的原理就是用的動態加載 script的src ,所以我們只能把參數通過 url的方式傳遞,所以jsonp的 type類型只能是get示例:
- $.ajax({
- url: 'http://192.168.1.114/yii/demos/test.php', //不同的域
- type: 'GET', // jsonp模式只有GET 是合法的
- data: {
- 'action': 'aaron'
- },
- dataType: 'jsonp', // 數據類型
- jsonp: 'backfunc', // 指定回調函數名,與服務器端接收的一致,并回傳回來
- })
使用JSONP 模式來請求數據的整個流程:客戶端發送一個請求,規定一個可執行的函數名(這里就是 jQuery做了封裝的處理,自動幫你生成回調函數并把數據取出來供success屬性方法來調用,而不是傳遞的一個回調句柄),服務器端接受了這個 backfunc函數名,然后把數據通過實參的形式發送出去
(在jquery 源碼中, jsonp的實現方式是動態添加<script>標簽來調用服務器提供的 js腳本。jquery 會在window對象中加載一個全局的函數,當 <script>代碼插入時函數執行,執行完畢后就 <script>會被移除。同時jquery還對非跨域的請求進行了優化,如果這個請求是在同一個域名下那么他就會像正常的 Ajax請求一樣工作。)
2、后臺Http請求轉發
使用HttpClinet轉發進行轉發(簡單的例子 不推薦使用這種方式)
- try {
- HttpClient client = HttpClients.createDefault(); //client對象
- HttpGet get = new HttpGet("http://localhost:8080/test"); //創建get請求
- CloseableHttpResponse response = httpClient.execute(get); //執行get請求
- String mes = EntityUtils.toString(response.getEntity()); //將返回體的信息轉換為字符串
- System.out.println(mes);
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
3、后臺配置同源Cors (推薦)
在SpringBoot2.0 上的跨域 用以下代碼配置 即可完美解決你的前后端跨域請求問題
- 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;
- /**
- * 實現基本的跨域請求
- * @author linhongcun
- *
- */
- @Configuration
- public class CorsConfig {
- @Bean
- public CorsFilter corsFilter() {
- final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
- final CorsConfiguration corsConfiguration = new CorsConfiguration();
- /*是否允許請求帶有驗證信息*/
- corsConfiguration.setAllowCredentials(true);
- /*允許訪問的客戶端域名*/
- corsConfiguration.addAllowedOrigin("*");
- /*允許服務端訪問的客戶端請求頭*/
- corsConfiguration.addAllowedHeader("*");
- /*允許訪問的方法名,GET POST等*/
- corsConfiguration.addAllowedMethod("*");
- urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
- return new CorsFilter(urlBasedCorsConfigurationSource);
- }
- }
4、使用SpringCloud網關
服務網關(zuul)又稱路由中心,用來統一訪問所有api接口,維護服務。
Spring Cloud Zuul通過與Spring Cloud Eureka的整合,實現了對服務實例的自動化維護,所以在使用服務路由配置的時候,我們不需要向傳統路由配置方式那樣去指定具體的服務實例地址,只需要通過Ant模式配置文件參數即可
5、使用nginx做轉發
現在有兩個網站想互相訪問接口 在http://a.a.com:81/A中想訪問 http://b.b.com:81/B 那么進行如下配置即可
然后通過訪問 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;
- }
- }
如果是兩個端口想互相訪問接口 在http://b.b.com:80/Api中想訪問 http://b.b.com:81/Api 那么進行如下配置即可
使用nginx轉發機制就可以完成跨域問題
- server {
- listen 80;
- server_name b.b.com;
- location /Api {
- proxy_pass http://b.b.com:81/Api;
- index index.html index.htm;
- }
- }
新聞熱點
疑難解答