日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【安全系列之跨域】跨域解决方案

發布時間:2024/10/5 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【安全系列之跨域】跨域解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、為什么會出現跨域問題

出于瀏覽器的同源策略限制。同源策略是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。

二、什么是跨域

當一個請求url的協議、域名、端口三者之間任意一個與當前頁面url不同即為跨域,舉幾個例子:

三、非同源限制

【1】無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB

【2】無法接觸非同源網頁的 DOM

【3】無法向非同源地址發送 AJAX 請求

四、跨域解決方法

跨域大致可以分為三種解決方案:

  • 服務端進行設置默認允許某些域名跨域訪問
  • 從客戶端入手想辦法繞開同源安全策略
  • 使用代理服務器
  • 不建議在前端利用什么 JSONP,iframe+domain 等來實現跨域請求,這種本質是繞過了欺騙了瀏覽器,起不到安全防護的作用。所以我們主要從服務端或者代理入手。
    跨域請求究竟發出去沒有?
    跨域并不是請求發不出去,請求能發出去,服務端能收到請求并正常返回結果,只是結果被瀏覽器攔截了。你可能會疑問明明通過表單的方式可以發起跨域請求,為什么 Ajax 就不會?因為歸根結底,跨域是為了阻止用戶讀取到另一個域名下的內容,Ajax 可以獲取響應,瀏覽器認為這不安全,所以攔截了響應。但是表單并不會獲取新的內容,所以可以發起跨域請求。同時也說明了跨域并不能完全阻止 CSRF,因為請求畢竟是發出去了。

    CORS

    目前標準的跨域解決方案是CORS,CORS 是跨域資源分享(Cross-Origin Resource Sharing)的縮寫。它是 W3C 標準,屬于跨源 AJAX 請求的根本解決方法。(有人容易將CORS和跨域劃等號,其實他們一個是問題一個是解決方案)

    它的實現則主要在服務端,它通過一些 HTTP Header 來限制可以訪問的域,例如頁面 A 需要訪問 B 服務器上的數據,如果 B 服務器上聲明了允許 A 的域名訪問,那么從 A 到 B 的跨域請求就可以完成。對于那些會對服務器數據產生副作用的 HTTP 請求,瀏覽器會使用OPTIONS 方法發起 一個預檢請求(preflight request),從而可以獲知服務器端是否允許該跨域請求,服務器端確認允許后,才會發起實際的請求。在預檢請求的返回中,服務器端也可以告知客戶端是否需要身份認證信息。我們只需要設置響應頭,即可進行跨域請求。主要是服務器端設置Access-Control-Allow-Origin頭

    *CORS 和前端沒什么關系,但是標準的CORS請求不對cookies做任何事情,既不發送也不改變。想要傳遞cookie,需要客戶端與服務端共同設置
    1、普通跨域請求:只需服務器端設置Access-Control-Allow-Origin
    2、帶cookie跨域請求:前后端都需要進行設置,當需要傳遞cookie時,Access-Control-Allow-Origin 不能設置為 * 號,必須為具體的一個域名。同時,服務端需要設置 Access-Control-Allow-Credentials 為 true。表示服務端同意發送cookie。客戶端需要設置Ajax請求屬性withCredentials=true,讓Ajax請求都帶上Cookie
    【前端設置】根據xhr.withCredentials字段判斷是否帶有cookie
    ①原生ajax

    var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容 // 前端設置是否帶cookie xhr.withCredentials = true; xhr.open('post', 'http://www.domain2.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin');xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {alert(xhr.responseText);} };``② jQuery ajax ```java $.ajax({url: 'http://www.test.com:8080/login',type: 'get',data: {},xhrFields: {withCredentials: true // 前端設置是否帶cookie},crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie });

    ③vue-resource

    Vue.http.options.credentials = true

    ④ axios

    axios.defaults.withCredentials = true

    【服務端設置】

    服務器端對于CORS的支持,主要是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。
    ① Java后臺

    /** 導入包:import javax.servlet.http.HttpServletResponse;* 接口參數中定義:HttpServletResponse response*/// 允許跨域訪問的域名:若有端口需寫全(協議+域名+端口),若沒有端口末尾不用加'/' response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); // 允許前端帶認證cookie:啟用此項后,上面的域名不能為'*',必須指定具體的域名,否則瀏覽器會提示 response.setHeader("Access-Control-Allow-Credentials", "true"); // 提示OPTIONS預檢時,后端需要設置的兩個常用自定義頭 response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");

    ② 如果你的SpringBoot版本在2.0以上,以下代碼配置即可完美解決你的前后端跨域請求問題:

    @Configuration public class CorsConfig {@Beanpublic 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);} }

    ③@CrossOrigin注解
    這個方法僅對Java有用。springboot中,在Controller類上添加一個 @CrossOrigin(origins ="*") 注解就可以實現對當前controller 的跨域訪問了,當然這個標簽也可以加到方法上,或者直接加到入口類上對所有接口進行跨域處理,注意這個注解只在JDK1.8版本以上才起作用。
    這個注解有些坑,對于復雜請求可能會有問題,參考方案
    https://blog.csdn.net/weixin_40910372/article/details/105126261

    代理

    webpack本地代理

    在webpack.config.js中利用 WebpackDevServer 配置本地代理,詳情配置查看devServer,如下簡單配置案例,這樣 http://localhost:8080/api/getUser.php 的請求就是后端的接口 http://192.168.25.20:8088/getUser.php

    devServer: {port: 8080,proxy: {"/api": {target: "http://192.168.25.20:8088" // 后端接口}}}

    【6】websocket

    Websocket 是 HTML5 的一個持久化的協議,它實現了瀏覽器與服務器的全雙工通信,同時也是跨域的一種解決方案。WebSocket 和 HTTP 都是應用層協議,都基于 TCP 協議。但是 WebSocket 是一種雙向通信協議,在建立連接之后,WebSocket 的 服務器與 客戶端都能主動向對方發送或接收數據。同時,WebSocket 在建立連接時需要借助 HTTP 協議,連接建立好了之后 client 與 server 之間的雙向通信就與 HTTP 無關了。

    【7】Nginx反向代理

    Nginx 實現原理類似于 Node 中間件代理,需要你搭建一個中轉 nginx 服務器,用于轉發請求。

    使用 nginx 反向代理實現跨域,是最簡單的跨域方式。只需要修改 nginx 的配置即可解決跨域問題,支持所有瀏覽器,支持 session,不需要修改任何代碼,并且不會影響服務器性能。

    我們只需要配置nginx,在一個服務器上配置多個前綴來轉發http/https請求到多個真實的服務器即可。這樣,這個服務器上所有url都是相同的域 名、協議和端口。因此,對于瀏覽器來說,這些url都是同源的,沒有跨域限制。而實際上,這些url實際上由物理服務器提供服務。這些服務器內的 javascript可以跨域調用所有這些服務器上的url。

    先下載nginx,然后將 nginx 目錄下的 nginx.conf 修改如下:

    server {#nginx監聽所有localhost:8080端口收到的請求listen 8080;server_name localhost;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;#localhost:8080 會被轉發到這里#同時, 后端程序會接收到 "192.168.25.20:8088"這樣的請求urllocation / {proxy_pass http://192.168.25.20:8088;}#localhost:8080/api/ 會被轉發到這里#同時, 后端程序會接收到 "192.168.25.20:9000/api/"這樣的請求urllocation /api/ {proxy_pass http://192.168.25.20:9000;}error_page 404 /404.html;location = /40x.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {} }

    寫在最后:
    不推薦的最后手段,前端解決跨域的9種方案:
    https://www.imooc.com/article/291931

    參考資料:
    https://blog.csdn.net/weixin_44862325/article/details/105605091?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-1.pc_relevant_paycolumn_v3&spm=1001.2101.3001.4242.2&utm_relevant_index=3
    https://blog.csdn.net/weixin_40910372/article/details/100068498?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164525961416780274141457%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164525961416780274141457&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-100068498.pc_search_insert_ulrmf&utm_term=%E5%90%8E%E7%AB%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98&spm=1018.2226.3001.4187

    總結

    以上是生活随笔為你收集整理的【安全系列之跨域】跨域解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。