国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

徹底弄懂跨域問題

CoorChice / 1218人閱讀

摘要:瀏覽器同源策略我們為何要研究跨域問題因為瀏覽器的同源策略規定某域下的客戶端在沒明確授權的情況下,不能讀寫另一個域的資源。

跨域,老生常談的問題 簡述

作為一只前端菜鳥,跨域方面只懂得JSONP和CORS,并未曾深入了解。但隨著春招越來越近,就算是菜鳥也要猛振翅膀。近幾日仔細研究了跨域問題,寫下這篇文章,希望對開發者們有所幫助。在讀本文前,希望您對以下知識略有了解。

瀏覽器同源策略

nodejs

iframe

docker, nginx

我們為何要研究跨域問題

因為瀏覽器的同源策略規定某域下的客戶端在沒明確授權的情況下,不能讀寫另一個域的資源。而在實際開發中,前后端常常是相互分離的,并且前后端的項目部署也常常不在一個服務器內或者在一個服務器的不同端口下。前端想要獲取后端的數據,就必須發起請求,如果不做一些處理,就會受到瀏覽器同源策略的約束。后端可以收到請求并返回數據,但是前端無法收到數據。

為何瀏覽器會制定同源策略

之所以有同源策略,其中一個重要原因就是對cookie的保護。cookie 中存著sessionID 。黑客一旦獲取了sessionID,并且在有效期內,就可以登錄。當我們訪問了一個惡意網站 如果沒有同源策略 那么這個網站就能通過js 訪問document.cookie 得到用戶關于的各個網站的sessionID 其中可能有銀行網站 等等。通過已經建立好的session連接進行攻擊,比如CSRF攻擊。
這里需要服務端配合再舉個例子,現在我扮演壞人 我通過一個iframe 加載某寶的登錄頁面 等傻傻的用戶登錄我的網站的時候 我就把這個頁面彈出 用戶一看 阿里唉大公司 肯定安全 就屁顛屁顛的輸入了密碼 注意 如果沒有同源策略 我這個惡意網站就能通過dom操作獲取到用戶輸入的值 從而控制該賬戶所以同源策略是絕對必要的.
還有需要注意的是同源策略無法完全防御CSRF。

多種跨域方法

跨域可以大概分為兩種目的

前后端分離時,前端為了獲取后端數據而跨域

為不同域下的前端頁面通信而跨域

為前后端分離而跨域 Cross Origin Resource Share (CORS)

CORS是一個跨域資源共享方案,為了解決跨域問題,通過增加一系列請求頭和響應頭,規范安全地進行跨站數據傳輸

請求頭主要包括
請求頭 解釋
Origin Origin頭在跨域請求或預先請求中,標明發起跨域請求的源域名。
Access-Control-Request-Method Access-Control-Request-Method頭用于表明跨域請求使用的實際HTTP方法
Access-Control-Request-Headers Access-Control-Request-Headers用于在預先請求時,告知服務器要發起的跨域請求中會攜帶的請求頭信息
with-credentials 跨域請求攜帶cookie
響應頭主要包括
響應頭 解釋
Access-Control-Allow-Origin Access-Control-Allow-Origin頭中攜帶了服務器端驗證后的允許的跨域請求域名,可以是一個具體的域名或是一個*(表示任意域名)。
Access-Control-Expose-Headers Access-Control-Expose-Headers頭用于允許返回給跨域請求的響應頭列表,在列表中的響應頭的內容,才可以被瀏覽器訪問。
Access-Control-Max-Age Access-Control-Max-Age用于告知瀏覽器可以將預先檢查請求返回結果緩存的時間,在緩存有效期內,瀏覽器會使用緩存的預先檢查結果判斷是否發送跨域請求。
Access-Control-Allow-Methods Access-Control-Allow-Methods用于告知瀏覽器可以在實際發送跨域請求時,可以支持的請求方法,可以是一個具體的方法列表或是一個*(表示任意方法)。
如何使用

客戶端只需按規范設置請求頭。

服務端按規范識別并返回對應響應頭,或者安裝相應插件,修改相應框架配置文件等。具體視服務端所用的語言和框架而定

SpringBoot 設置CORS例子

一個spring boot項目中關于CORS配置的一段代碼

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 跨域

jsonp的原理就是借助HTML中的

后端代碼(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...");

在該例子中,前臺收到的res是這樣的

前端頁面是這樣的

注意

JSONP既是利用了,那么就只能支持GET請求。其他請求無法實現

nginx 反向代理實現跨域 思路

既然瀏覽器有同源策略限制,那我們把前端項目和前端要請求的api接口地址放在同源下不就可以了?再結合web服務器提供的反向代理,便可以在前端和后端都不做配置的情況下解決跨域問題。

以nginx為例

后端真實后臺地址:http://xxx.xxx.xxx.xxx:8085 后臺地址使用tomcat部署的spring boot項目 名為gsms_test

nginx服務器地址: http://xxx.xxx.xxx.xxx:8082

tomcat和nginx都是用docker架設的,做了端口轉發

使用條件:開發環境為linux系統

nginx /etc/nginx/conf.d/default.conf配置代碼如下

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;
    #}
}

不同域下頁面通信而跨域 window.name + iframe 跨域

window.name是瀏覽器中一個窗口所共享的數據,在不同的頁面(甚至不同域名)加載后依舊存在(如果沒修改則值不會變化),并且可以支持非常長的 name 值(2MB)。比如 a域的某頁面想獲取b域某頁面的數據,可以在b域中修改window.name值,a域切換到b域再切回來即可得到b域的window.name值。可是我們在開發中肯定不想頁面切來切去,所以就要結合iframe來實現。

示例 (以thinkjs實現)

a 域代碼如下





A 域


server A

b 域代碼





New ThinkJS Application


  

server 2

注意

由于受同源策略限制,父頁面獲取跨域的iframe頁面的信息不全,所以要在iframe的window.name被B域修改后,轉為A域下的任一頁面(該一面不得修改window.name),在進行獲取。

代理頁面 + iframe 實現跨域訪問

由于iframe與父頁面相互訪問也受同源策略限制,所以要借助一代理頁面實現跨域。

個人認為有些麻煩,若有興趣請看前端如何用代理頁面解決iframe跨域訪問的問題?

總結

以上幾種皆是本人用過或測試過的跨域方法,還有postMessage,WebSocket等跨域方法由于從未接觸不做說明。在項目中具體使用那些方法還需具體考慮各種問題

情況 方法
只有GET請求 JSONP
對兼容性及瀏覽器版本無要求 CORS
對兼容性及瀏覽器版本有要求 iframe 或 服務器反向代理(linux 環境下開發)
本文參考

經驗 跨域方案

CORS——跨域請求那些事兒

前端如何用代理頁面解決iframe跨域訪問的問題?

前端常見的跨域解決方案(全)

CORS與服務器反向代理的優劣對比

圖解正向代理、反向代理、透明代理

謝謝

本文如有錯誤,歡迎指出
本人郵箱 xbc18304999858@gmail.com

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100975.html

相關文章

  • 徹底弄懂跨域問題

    摘要:用于告知瀏覽器可以將預先檢查請求返回結果緩存的時間,在緩存有效期內,瀏覽器會使用緩存的預先檢查結果判斷是否發送跨域請求。 跨域,老生常談的問題 簡述 作為一只前端菜鳥,跨域方面只懂得JSONP和CORS,并未曾深入了解。但隨著春招越來越近,就算是菜鳥也要猛振翅膀。近幾日仔細研究了跨域問題,寫下這篇文章,希望對開發者們有所幫助。在讀本文前,希望您對以下知識略有了解。 瀏覽器同源策略 n...

    rose 評論0 收藏0
  • 一篇文章搞明白CORS跨域

    摘要:跨域實在是面試官一個人的利器。首先,什么是是一個標準,全稱是跨域資源共享。它的值是一個布爾值,表示是否允許發送。設為,即表示服務器明確許可,可以包含在請求中,一起發給服務器。 面試問到數據交互的時候,經常會問跨域如何處理。大部分人都會回答JSONP,然后面試官緊接著就會問:JSONP缺點是什么啊?這個時候坑就來了,如果面試者說它支持GET方式,然后面試官就會追問,那如果POST方式發送...

    tanglijun 評論0 收藏0
  • 前端經典文章

    摘要:上周末看這篇文章時,偶有靈光,所以,分享出來給大家一起看看前端面試四月二十家前端面試題分享請各位讀者添加一下作者的微信公眾號,以后有新的文章,將在微信公眾號直接推送給各位,非常感謝。 前端切圖神器 avocode 有了這個神器,切圖再也腰不酸,腿不疼了。 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果讀完本文還不懂,...

    lowett 評論0 收藏0
  • 徹底弄懂JS中閉包

    閉包概念:   閉包就是有權訪問另一個函數作用域中變量的函數. 分析這句話:   1.閉包是定義在函數中的函數.  2.閉包能訪問包含函數的變量.  3.即使包含函數執行完了, 被閉包引用的變量也得不到釋放. 例子分析-1: function add(){ var i = 0 arr = []; ...

    DevYK 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<