日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

前后端分離和跨域問題的詳細(xì)解決方案(CORS的原理)

瀏覽:251日期:2022-06-06 16:55:59
目錄
  • 前后端分離
    • 前后端分離的好處
    • 個(gè)人理解上存在兩種解釋
  • 跨域問題存在的原因
    • 跨域問題的解決方案
      • 修改瀏覽器配置解決跨域
        • 使用jsonp解決跨域
          • CORS解決跨域
            • 服務(wù)軟件實(shí)現(xiàn)跨域
              • 基于Apache的服務(wù)
              • 基于Nignx的服務(wù)
          • 總結(jié)

            前后端分離

            前后端分離的好處

            1. 最大的好處就是前端JS可以做很大部分的數(shù)據(jù)處理工作,對(duì)服務(wù)器的壓力減小到最小。
            2. 后臺(tái)錯(cuò)誤不會(huì)直接反映到前臺(tái),錯(cuò)誤接秒較為友好。
            3. 由于后臺(tái)是很難去探知前臺(tái)頁面的分布情況,而這又是JS的強(qiáng)項(xiàng),而JS又是無法獨(dú)立和服務(wù)器進(jìn)行通訊的。所以單單用后臺(tái)去控制整體頁面,又或者只靠JS完成效果,都會(huì)難度加大,前后臺(tái)各盡其職可以最大程度的減少開發(fā)難度。

            個(gè)人理解上存在兩種解釋

            • 第一種只是單純的前后端分離,實(shí)在物理層面上的,將View層的任務(wù)分配給前端,Controller和Model層給后端,這就存在一個(gè)問題,就是后端的同事需要去關(guān)注前端的展示邏輯、而前端只要存在變化,后端的數(shù)據(jù)處理需要做相應(yīng)的改變。
            • 第二種是基于職責(zé)層面上的分離,將View和Controller層分配的前端,后端只處理Model和業(yè)務(wù)處理,這就需要Controller使用Node.js,M-V-C對(duì)應(yīng)的是JAVA/PHP-JAVASCRIPT、HTML、CSS-Node.js。

            跨域問題存在的原因

            隨著前后端分離技術(shù)的越來越盛行,跨域問題也逐漸凸顯了出來。跨域問題的根本原因:因?yàn)闉g覽器收到同源策略的限制,當(dāng)前域名的js只能讀取同域下的窗口屬性。什么叫做同源策略?就是不同的域名, 不同端口, 不同的協(xié)議不允許共享資源的,保障瀏覽器安全。同源策略是針對(duì)瀏覽器設(shè)置的門檻。如果繞過瀏覽就能實(shí)現(xiàn)跨域,所以說早期的跨域都是打著安全路數(shù)的擦邊球,都可以認(rèn)為是 hack 處理。這一段是我從別的地方cp過來的,大家將就著看吧。

            這里要注意的是,只有訪問類型為xhr(XMLHttpRequest)的才會(huì)出現(xiàn)跨域。

            跨域問題的解決方案

            • 修改瀏覽器的設(shè)置
            • 修改請(qǐng)求的方式:jsonp
            • CORS

            修改瀏覽器配置解決跨域

            以Google Chrome為例,瀏覽器以

            "C:\ProgramFiles(x86)\Google\Chrome\Application\chrome.exe"
            --disable-web-security--user-data-dir

            中模式打開,右鍵點(diǎn)擊瀏覽器快捷方式,在目標(biāo)中輸入上述代碼即可解決(不推薦)。

            使用jsonp解決跨域

            JQuery中的正常AJAX請(qǐng)求代碼片段

            $("#demo1").click(function(){    $.ajax({url : "http://www.tpadmin.top/Index/Test/crossDomain",data : {},type : "get",success : function (res) {    //No "Access-Control-Allow-Origin" header is present on the requested resource. Origin "http://127.0.0.1" is therefore not allowed access. 在執(zhí)行時(shí)候報(bào)出的錯(cuò)誤,這代表了跨域錯(cuò)誤    alert(res);}    });});?

            JQuery中的使用JSONP的AJAX請(qǐng)求代碼:

            $("#demo2").click(function(){    $.ajax({url : "http://www.tpadmin.top/Index/Test/crossDomain",data : {},type : "get",dataType : "jsonp", success : function (res) {    alert(res);}    });});

            這時(shí)候我們看到 請(qǐng)求的網(wǎng)址自動(dòng)變成了

            http://www.tpadmin.top/Index/Test/crossDomain?callback=jQuery331015214102388989237_1534993962395&_=1534993962396

            這是為什么呢?原來由于跨域訪問的只限制xhr類型的請(qǐng)求(上文中已經(jīng)說了),所以js中就利用了這一特點(diǎn),讓服務(wù)端不在返回的是一個(gè)JSON格式的數(shù)據(jù),而是返回一段JS代碼,將JSON的數(shù)據(jù)以參數(shù)的形式傳遞到這個(gè)函數(shù)中,而函數(shù)的名稱就是callback參數(shù)的值,所以我們還需要修改服務(wù)端的代碼,代碼如下:

            <?php    $callback = isset($_GET["callback"])?$_GET["callback"]:"";    if (!empty($callback)) {$arr = ["code" => 200, "name" => "cui"];$data = json_encode($arr);exit($callback . "(" . $data . ")");    }?>

            OK,現(xiàn)在問題解決了,但是JSONP存在著諸多限制,下面將列出兩個(gè)個(gè)我知道的:

            JSONP只支持GET請(qǐng)求,什么?你要提交表單,sorry,此路不通它只支持跨域HTTP請(qǐng)求

            雖然只有兩個(gè),但是讓很多人不得不放棄它,所以出現(xiàn)了下面的解決辦法。

            CORS解決跨域

            回歸問題本質(zhì),跨域問題為什么會(huì)產(chǎn)生,上面已經(jīng)說了,是由于瀏覽器的限制,那么在執(zhí)行過程中有什么不同,下面兩張度分析一下(主要看請(qǐng)求頭的部分):

            這是非跨域請(qǐng)求

            這是跨域請(qǐng)求

            這時(shí)我們發(fā)現(xiàn)跨域訪問的請(qǐng)求頭中存在Origin的字段,用來記錄當(dāng)前的訪問域名,我們可以再服務(wù)端增加一個(gè)響應(yīng)頭Access-Control-Allow-Origin來告訴瀏覽器我們支持它獲取就可以了,代碼實(shí)現(xiàn):

            <?phpheader("Access-Control-Allow-Origin:http://127.0.0.1");$arr = ["code" => 200, "name" => "cui"];echo $data = json_encode($arr);?>

            那如果我有多個(gè)域名進(jìn)行跨域訪問呢

            <?php$requestHeader = getallheaders();$origin = isset($requestHeader["Origin"])?$requestHeader["Origin"]:"";switch ($origin) {    case "http://127.0.0.1":header("Access-Control-Allow-Origin:http://127.0.0.1");break;    case "http://localhost":header("Access-Control-Allow-Origin:http://localhost");break;    default:break;}$arr = ["code" => 200, "name" => "cui"];echo $data = json_encode($arr);//注意,不支持下面這種寫法//header("Access-Control-Allow-Origin:http://localhost,http://127.0.0.1");?>

            或者直接寫成(很不安全,不推薦這么寫)

            <?phpheader("Access-Control-Allow-Origin:*");$arr = ["code" => 200, "name" => "cui"];echo $data = json_encode($arr);?>

            到這里,其實(shí)已經(jīng)結(jié)束了,但還有一些其他的特殊情況

            • 請(qǐng)求方法不是GET、HEAD、POST
            • 請(qǐng)求頭中存在自定義頭
            • Content-Type不是text/plain、multipart/form-data、application/x-www-form-urlencoded
            • 希望獲取到服務(wù)端的Cookie

            為了應(yīng)對(duì)種種限制,我們?cè)賮砜匆欢未a

            $("#demo1").click(function(){    $.ajax({url : "http://cui.tpadmin.top/crossDomain.php",data : {},type : "PUT",contentType : "application/json",header: {    token:"asdfgqwerttyyazxcvbvb"},success : function (res) {    alert(res);}    });});

            雖然我們?cè)诜?wù)端加入了Access-Control-Allow-Origin響應(yīng)頭,但是如果出現(xiàn)上面所說的情況時(shí),我們需要做一些特殊的設(shè)置,修改服務(wù)端代碼為:

            <?php//這里增加了兩行代碼header("Access-Control-Allow-Headers:Content-Type");header("Access-Control-Allow-Methods:PUT");$requestHeader = getallheaders();$origin = isset($requestHeader["Origin"])?$requestHeader["Origin"]:"";switch ($origin) {    case "http://127.0.0.1":header("Access-Control-Allow-Origin:http://127.0.0.1");break;    case "http://localhost":header("Access-Control-Allow-Origin:http://localhost");break;    default:break;}$arr = ["code" => 200, "name" => "cui"];echo $data = json_encode($arr);?>

            這里雖然成功了,但是我們發(fā)現(xiàn)每次請(qǐng)求的時(shí)候會(huì)出現(xiàn)兩條請(qǐng)求記錄(這個(gè)可不是我請(qǐng)求了兩次,看下面截圖)

            這里我們需要進(jìn)行一下區(qū)分(簡(jiǎn)單請(qǐng)求模式與非簡(jiǎn)單請(qǐng)求模式)

            • 請(qǐng)求方法只能為GET、HEAD、POST
            • 請(qǐng)求頭中無自定義頭
            • Content-Type必須為text/plain、multipart/form-data、application/x-www-form-urlencoded

            符合以上條件的為簡(jiǎn)單請(qǐng)求,否則為非簡(jiǎn)單請(qǐng)求,注意,非簡(jiǎn)單請(qǐng)求中,瀏覽器會(huì)默認(rèn)發(fā)送兩條請(qǐng)求,第一條為預(yù)檢請(qǐng)求(OPTION),第二條為AJAX的請(qǐng)求,處于服務(wù)器的性能考量,我們需要將預(yù)檢命令進(jìn)行緩存,而不是每次都執(zhí)行預(yù)檢請(qǐng)求,我們可以修改代碼如下:

            <?phpheader("Access-Control-Allow-Headers:Content-Type");header("Access-Control-Allow-Methods:PUT");//看這里header("Access-Control-Max-Age:3600");$requestHeader = getallheaders();$origin = isset($requestHeader["Origin"])?$requestHeader["Origin"]:"";switch ($origin) {    case "http://127.0.0.1":header("Access-Control-Allow-Origin:http://127.0.0.1");break;    case "http://localhost":header("Access-Control-Allow-Origin:http://localhost");break;    default:break;}$arr = ["code" => 200, "name" => "cui"];echo $data = json_encode($arr);?>

            這次我請(qǐng)求了兩次,發(fā)現(xiàn)第二次請(qǐng)求沒有發(fā)送預(yù)檢請(qǐng)求,新增加的代碼代表允許緩存的時(shí)間(3600S)。

            另外還有一些常用的方法,我都放到這里了,有需要的小伙伴可以參考

            <?php//支持Cookieheader("Access-Control-Allow-Credentials:true");//支持自定義頭header("Access-Control-Allow-Headers:token,Content-Type,...");??

            由于篇幅有限,Cookie的例子小伙伴們自己做就可以了,使用Cookie的時(shí)候需要注意Access-Control-Allow-Origin不可設(shè)置為*。

            服務(wù)軟件實(shí)現(xiàn)跨域

            上面的例子實(shí)現(xiàn)了跨域訪問,但是如果我不想在代碼中修改,還有其他的方法嗎,當(dāng)然有了,我們可以直接修改服務(wù)軟件,下面將從最常用的Apache與Nignx兩個(gè)方面說明

            基于Apache的服務(wù)

            <VirtualHost *:80>  ServerName localhost  ServerAlias localhost  DocumentRoot "${INSTALL_DIR}/www"    Header always set Access-Control-Allow-Header "PUT"  Header always set Access-Control-Allow-Credentials "true"  Header always set Access-Control-Max-Age "3600"  #這里設(shè)置的為全匹配  Header always set Access-Control-Allow-Origin "expr=%{req:origin}"  #這里設(shè)置的為全匹配  Header always set Access-Control-Allow-Headers "expr=%{req:Access-Control-Allow-Headers}"    <Directory "${INSTALL_DIR}/www/">    Options +Indexes +Includes +FollowSymLinks +MultiViews    AllowOverride All    Require local  </Directory></VirtualHost> 

            這里說明一下,由于Apache都是模塊管理,所以這里要想使用Header的話,需要加載mod_headers.so這個(gè)模塊,去看一下自己的主配置文件,這個(gè)模塊是否開啟,如果沒有開啟,apache會(huì)啟動(dòng)失敗的。

            LoadModule headers_module modules/mod_headers.so

            由于本人學(xué)藝不精,Apache的配置中的判斷沒有完全鬧懂,所以這里沒有進(jìn)行區(qū)分的匹配,如果有大神知道,請(qǐng)指導(dǎo)一下,不勝感激。

            基于Nignx的服務(wù)

            在nignx服務(wù)的配置中修改為如下代碼(注意位置,這個(gè)例子是修改本地的nignx,沒有域名,如果沒有熟悉過nignx的小伙伴可以自行百度)。

            server {    listen       80 default_server;    listen       [::]:80 default_server;    server_name  _;    root /usr/share/nginx/html;    # Load configuration files for the default server block.    include /etc/nginx/default.d/*.conf;    location / {    #支持其他請(qǐng)求    add_header Access-Control-Allow-Methods PUT;    #設(shè)置預(yù)檢請(qǐng)求的緩存    add_header Access-Control-Max-Age 3600;    #允許Cookie    add_header Access-Control-Allow-Credentials true;    #這里最好做判斷,怕麻煩的話就寫*,但是不建議    if ($http_origin = http://localhost){    add_header Access-Control-Allow-Origin http://localhost;    }    if ($http_origin = http://127.0.0.1){    add_header Access-Control-Allow-Origin http://127.0.0.1;    }    #為了方便,這樣寫了    add_header Access-Control-Allow-Headers $http_access_control_request_headers;    if ($request_method = OPTIONS){    return 200;    }    }    error_page 404 /404.html;location = /40x.html {    }    error_page 500 502 503 504 /50x.html;location = /50x.html {    }}

            另外再說一句,如果您使用的是JAVA的話,可以嘗試一下正反向代理。

            總結(jié)

            到此這篇關(guān)于前后端分離和跨域問題解決的文章就介紹到這了,更多相關(guān)前后端分離和跨域解決內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

            標(biāo)簽: PHP
            日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
            国产精品麻豆久久| 蜜臀精品一区二区三区在线观看| 日韩在线卡一卡二| 亚洲欧美日韩一区在线观看| 私拍精品福利视频在线一区| 黑森林国产精品av| 日韩影院二区| 日韩和的一区二在线| 国产精品玖玖玖在线资源| 国产免费av国片精品草莓男男| 欧美一区二区三区久久| 国产亚洲第一伦理第一区| 欧美性www| 麻豆国产91在线播放| 久久精品国产999大香线蕉| 麻豆精品av| 精品中文在线| 日韩毛片视频| 午夜精品影院| 亚洲免费资源| 日本欧美在线| 国产欧美日韩精品高清二区综合区 | 91精品啪在线观看国产18| 深夜福利视频一区二区| 999国产精品| 丝袜亚洲精品中文字幕一区| 天海翼亚洲一区二区三区| 国产精品网站在线看| 国产精品1区| 成午夜精品一区二区三区软件| 丁香六月综合| 视频一区中文| 日韩有码av| 国产精品香蕉| 欧美gv在线| 国产精品丝袜xxxxxxx| 亚洲另类黄色| 欧美黑人做爰爽爽爽| 97精品一区二区| 欧美色图国产精品| 亚洲久久视频| 久久亚洲黄色| 亚洲精品网址| 日韩福利在线观看| 水蜜桃久久夜色精品一区| 久久国产免费| 午夜电影一区| av日韩中文| 久久xxxx精品视频| 欧美国产先锋| 最新亚洲一区| 欧美日韩中出| 91精品国产成人观看| 亚洲三级av| 日韩欧美精品| 亚洲免费专区| 欧美日韩视频网站| 亚洲aa在线| 日韩欧美自拍| 日韩av三区| 99久久夜色精品国产亚洲1000部| 亚洲欧美在线综合| 欧美男人天堂| 亚洲精品成a人ⅴ香蕉片| 国产夫妻在线| 亚洲视频国产精品| 成人在线观看免费视频| 欧美.日韩.国产.一区.二区| 日本aⅴ亚洲精品中文乱码| 香蕉成人av| 国产日韩一区二区三区在线播放| 久久人人精品| 久久福利在线| 日韩制服丝袜先锋影音| 日韩一区二区在线免费| 青草综合视频| 午夜日韩在线| 久久久久久久欧美精品| 亚洲ww精品| 日韩一区电影| 国产精品美女在线观看直播| 欧美日韩少妇| 丁香婷婷久久| 日韩精品亚洲专区在线观看| 久久婷婷亚洲| 精品亚洲二区| 日韩欧美激情| 五月综合激情| 日韩精品1区| 麻豆高清免费国产一区| 乱人伦精品视频在线观看| 精品国产亚洲一区二区在线观看| 久久高清免费观看| 亚洲成av在线| 精品亚洲成人| 国产精品igao视频网网址不卡日韩| 国产亚洲毛片| 亚洲高清成人| 国产精品成久久久久| 日本va欧美va欧美va精品| 鲁大师成人一区二区三区| 日韩成人高清| 欧美久久天堂| 风间由美中文字幕在线看视频国产欧美| 日本在线成人| 欧美日韩国产在线一区| 91精品蜜臀一区二区三区在线| 精品一区二区男人吃奶| 青青草国产精品亚洲专区无| 午夜av一区| 欧美日韩在线播放视频| 91麻豆国产自产在线观看亚洲| 国产精品v一区二区三区| 日韩av资源网| 日韩动漫一区| 亚洲精品美女91| 亚洲精品在线二区| 日本不卡不码高清免费观看| 亚洲一级大片| 四虎精品一区二区免费| 亚洲激情精品| 夜夜精品视频| 久久高清免费观看| 亚洲一区欧美| 亚洲精品影视| 日产欧产美韩系列久久99| 日韩精品第二页| 在线精品视频一区| 日欧美一区二区| 日本aⅴ精品一区二区三区| 日韩欧美中文字幕电影| 日本午夜精品久久久久| 日本午夜精品久久久| 国产亚洲一区二区三区啪| 日本午夜免费一区二区 | 国产精品一区高清| 日韩精品免费视频一区二区三区| 婷婷精品久久久久久久久久不卡| 亚洲另类av| 日韩黄色在线观看| 日韩成人在线看| 欧美1区2区3| sm捆绑调教国产免费网站在线观看 | 久久中文亚洲字幕| 国内精品福利| 日韩在线播放一区二区| 亚洲精品一级| 国产三级精品三级在线观看国产| 国产精品免费不| 日本一二区不卡| 蜜臀国产一区| 欧美在线亚洲| 日韩欧美中文在线观看| 国产精品xxx在线观看| 久久久男人天堂| 欧美一级精品| 亚洲精品九九| 久久精品资源| 日本久久黄色| 亚洲欧美成人综合| 日本色综合中文字幕| 日韩成人免费| 亚洲一区二区三区高清不卡| 日本天堂一区| 日韩国产专区| 视频在线观看一区二区三区| 91福利精品在线观看| 国产精品99视频| 婷婷成人基地| 日本成人在线不卡视频| 97国产成人高清在线观看| 亚洲女同中文字幕| 日韩高清电影一区| 欧美精品91| 国产综合精品一区| 91精品国产经典在线观看| 亚洲综合电影| 日本不卡视频在线观看| 久久男人天堂| 在线观看一区| 国产成人精品免费视| 亚洲国产专区| 国产日产一区| 群体交乱之放荡娇妻一区二区| 午夜电影一区| 在线人成日本视频| 日韩美女精品| 久久精品免费一区二区三区 | 国产精品88久久久久久| 日韩激情啪啪| 欧美亚洲国产一区| 久久国产三级精品| 久久精品高清| 日本麻豆一区二区三区视频| 成人自拍av| 婷婷亚洲成人| 国产专区精品| 免费日韩av片| 成人午夜亚洲| 最新国产精品视频|