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

資訊專欄INFORMATION COLUMN

徹底弄懂跨域問題

rose / 2746人閱讀

摘要:用于告知瀏覽器可以將預(yù)先檢查請求返回結(jié)果緩存的時間,在緩存有效期內(nèi),瀏覽器會使用緩存的預(yù)先檢查結(jié)果判斷是否發(fā)送跨域請求。

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

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

瀏覽器同源策略

nodejs

iframe

docker, nginx

我們?yōu)楹我芯靠缬騿栴}

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

多種跨域方法

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

前后端分離時,前端為了獲取后端數(shù)據(jù)而跨域

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

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

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

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

客戶端只需按規(guī)范設(shè)置請求頭。

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

SpringBoot 設(shè)置CORS例子

一個spring boot項目中關(guān)于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 相關(guān)配置的緩存
        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返回設(shè)置
    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請求。其他請求無法實現(xiàn)

nginx 反向代理實現(xiàn)跨域 思路

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

以nginx為例

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

nginx服務(wù)器地址: http://xxx.xxx.xxx.xxx:8082

tomcat和nginx都是用docker架設(shè)的,做了端口轉(zhuǎn)發(fā)

使用條件:開發(fā)環(huán)境為linux系統(tǒng)

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/; # 前端本機地址,實現(xiàn)自動更新
        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是瀏覽器中一個窗口所共享的數(shù)據(jù),在不同的頁面(甚至不同域名)加載后依舊存在(如果沒修改則值不會變化),并且可以支持非常長的 name 值(2MB)。比如 a域的某頁面想獲取b域某頁面的數(shù)據(jù),可以在b域中修改window.name值,a域切換到b域再切回來即可得到b域的window.name值。可是我們在開發(fā)中肯定不想頁面切來切去,所以就要結(jié)合iframe來實現(xiàn)。

示例 (以thinkjs實現(xiàn))

a 域代碼如下





A 域


server A

b 域代碼





New ThinkJS Application


  

server 2

注意

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

代理頁面 + iframe 實現(xiàn)跨域訪問

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

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

總結(jié)

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

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

經(jīng)驗 跨域方案

CORS——跨域請求那些事兒

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

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

CORS與服務(wù)器反向代理的優(yōu)劣對比

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

謝謝

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/40283.html

相關(guān)文章

  • 徹底弄懂跨域問題

    摘要:瀏覽器同源策略我們?yōu)楹我芯靠缬騿栴}因為瀏覽器的同源策略規(guī)定某域下的客戶端在沒明確授權(quán)的情況下,不能讀寫另一個域的資源。 跨域,老生常談的問題 簡述 作為一只前端菜鳥,跨域方面只懂得JSONP和CORS,并未曾深入了解。但隨著春招越來越近,就算是菜鳥也要猛振翅膀。近幾日仔細研究了跨域問題,寫下這篇文章,希望對開發(fā)者們有所幫助。在讀本文前,希望您對以下知識略有了解。 瀏覽器同源策略 n...

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

    摘要:跨域?qū)嵲谑敲嬖嚬僖粋€人的利器。首先,什么是是一個標(biāo)準(zhǔn),全稱是跨域資源共享。它的值是一個布爾值,表示是否允許發(fā)送。設(shè)為,即表示服務(wù)器明確許可,可以包含在請求中,一起發(fā)給服務(wù)器。 面試問到數(shù)據(jù)交互的時候,經(jīng)常會問跨域如何處理。大部分人都會回答JSONP,然后面試官緊接著就會問:JSONP缺點是什么???這個時候坑就來了,如果面試者說它支持GET方式,然后面試官就會追問,那如果POST方式發(fā)送...

    tanglijun 評論0 收藏0
  • 前端經(jīng)典文章

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

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

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

    DevYK 評論0 收藏0

發(fā)表評論

0條評論

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