第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

ajax跨域完全講解

曉風(fēng)輕 全棧工程師
難度中級
時長 1小時40分
學(xué)習(xí)人數(shù)
綜合評分9.67
119人評價 查看評價
9.7 內(nèi)容實用
9.6 簡潔易懂
9.7 邏輯清晰
  • 為什么發(fā)生Ajax跨域?

    1、瀏覽器顯示?

    2、訪問的路徑不是本地的

    3、發(fā)送的請求是XMLHttprequest的請求

    查看全部
  • csrf filter

    查看全部
  • 為什么會發(fā)生ajax跨域/ 跨域的場景

    總的來說, 產(chǎn)生跨域問題有3個原因: ?瀏覽器的限制, 跨域, xhr(XMLHttpRequest) 請求; 這三個條件同時滿足才會產(chǎn)生跨域安全問題

    1. 瀏覽器的限制

    一句話解釋就是: 因為發(fā)送請求時跨域了所以瀏覽器報跨域問題

    跨域不成功和后臺服務(wù)器沒有關(guān)系, 不是因為后臺不允許前臺調(diào)用, 真正的原因是瀏覽器出于安全考慮, 會對發(fā)送的不同源跨域請求進行安全校驗,校驗不通過時就會報跨域錯誤。

    這個時候可能你的請求已經(jīng)發(fā)送成功并且返回了數(shù)據(jù), 但控制臺報了一條跨域錯誤, 說明服務(wù)器后臺式?jīng)]有任何限制的, ?前臺已經(jīng)訪問到了后臺, ?是瀏覽器報的錯; 說白了就是瀏覽器多管閑事, 而不是后臺不允許

    1. 跨域: 發(fā)出去的請求不是本域的. ?前臺發(fā)送的請求里面和后臺的 協(xié)議, 域名, 端口任何一個不一樣, 瀏覽器都會認(rèn)為是跨域; 比如前臺是localhost:8080端口, 請求的是localhost:8081端口 , 雖然域名相同, 但端口不一樣, 所以跨域了;

    2. 發(fā)送的是 XHR(XMLHttpRequest) 請求 (也是最重要的原因); 只要發(fā)送的不是XHR請求, 比如發(fā)送的請求Type為jsonp, 就算是跨域了, 瀏覽器也不會報跨域安全問題


    spacer.gif


    跨域解決方案

    • 命令行啟動參數(shù)修改

    • Cors, 在響應(yīng)頭里面添加字段

    • nodejs可以引入第三方包cors

    • nginx反向代理實現(xiàn)跨域(proxy_pass模塊)

    • Vue.config.js里面配置devServer的proxy

    • 谷歌的插件allow cors可以解決谷歌瀏覽器里面的跨域

    • webSocket本身不存在跨域的問題,所以我們可以利用webSocket來進行非同源中間的通信

    spacer.gif

    1. 從瀏覽器出發(fā), 讓瀏覽器不去做跨域的限制;

      方法1: 瀏覽器禁止跨域安全檢查

      思路: 通過命令行修改瀏覽器啟動參數(shù), 讓瀏覽器不進行跨域安全校驗, 從而允許跨域;

      做法: 命令行啟動瀏覽器后添加參數(shù) ?- -disable-web-security; 如 chrome --disable-web-security, 這個參數(shù)的作用是禁止瀏覽器進行跨域安全檢查;

      spacer.gif

      缺陷:

      ?總結(jié): 雖然可以解決跨域, 但是這種方式價值不大, 因為需要用戶手動修改, 而且這種改動是客戶端的改動, 不太實用, 而在實際項目中, 主要是對服務(wù)端進行修改來實現(xiàn)瀏覽器支持跨域;

      spacer.gif


      1. 每次都需要通過命令行啟動參數(shù)來啟動瀏覽器, 過于繁瑣

      2. 該方法會導(dǎo)致穩(wěn)定性和安全性有所下降

      3. 該方法是客戶端方法的改動, 在實際使用中, 要每個客戶端都禁止瀏覽器跨域檢查是不太現(xiàn)實的, 實用性較低

    2. JSONP (json with padding; jsonp 是json的一種補充使用) 避免發(fā)生跨域, ?因為只有xhr請求才會可能發(fā)生跨域, ?而jsonp 的請求類型不是xhr, 而且主要是通過動態(tài)創(chuàng)建script腳本, 利用script標(biāo)簽向不同源接口請求資源可以跨域的特點, 在script里面發(fā)送跨域請求, 獲取其他來源動態(tài)生成的json數(shù)據(jù), ?所以不會產(chǎn)生跨域問題;

      jsonp 與ajax 請求的區(qū)別


      思路: JSONP是一個非官方協(xié)議, 是一個約定, 它約定如果發(fā)送請求的時候在script標(biāo)簽里攜帶一個 callback 參數(shù), callback 的值是一個頁面中定義好的函數(shù)名, ?后臺檢測到 callback 就知道這是一個jsonp請求, 這時服務(wù)器返回的數(shù)據(jù)就會由原來的json對象改為js代碼;

      函數(shù)是瀏覽器定義的, 處理邏輯瀏覽器寫; ?數(shù)據(jù)是 服務(wù)器返回的, ?到底是什么數(shù)據(jù) 服務(wù)器決定;


      實現(xiàn)原理: 前臺使用 ajax 的 get 請求, 將 dataType 設(shè)為 'jsonp' , 服務(wù)器創(chuàng)建一個類并繼承抽象類 ?AbstractJsonResponseBodyAdvice, 最后注解 @ControllerAdvice;


      具體實現(xiàn)流程:


      補充: jsonp請求里除了callback參數(shù)外, 還一個下劃線 _ ? 參數(shù),參數(shù)值是一串隨機數(shù)字, 它的作用主要是防止請求被緩存, 如果需要緩存的話, ?可以在ajax請求里面加上 cache: true, 表示結(jié)果可以被緩存;

      spacer.gifspacer.gif



      JSONP優(yōu)缺點

      JSONP優(yōu)點是簡單兼容性好,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。

      缺點:


      5bbca6b10001e5aa05000211.jpg


    • 不安全,可能會遭受XSS攻擊;

    • 發(fā)送的不是xhr請求; xhr的一些事件, 異步功能jsonp都沒有;

    • 僅支持get方法, 不能滿足實際開發(fā)需求; jsonp是通過動態(tài)創(chuàng)建script發(fā)請求, script 只支持get

    • 服務(wù)器需要改動代碼來支持跨域, 當(dāng)接口不是我們自己的代碼無法改動時, jsonp就無能為力了;

    • 聲明一個回調(diào)函數(shù),其函數(shù)名(如show)當(dāng)做參數(shù)值,要傳遞給跨域請求數(shù)據(jù)的服務(wù)器,函數(shù)形參為服務(wù)器返回的data。

    • 創(chuàng)建一個<script>標(biāo)簽,把跨域的API接口地址賦值給script的src 并且在這個地址中攜帶這個show 函數(shù)名(通過問號傳參:?callback=show)。

    • 服務(wù)器接收到請求后,把傳遞進來的函數(shù)名和它需要給你的數(shù)據(jù)拼接成一個字符串,例如:傳遞進去的函數(shù)名是show,它準(zhǔn)備好的數(shù)據(jù)是show('你好么')。

    • 服務(wù)器把數(shù)據(jù)返回給瀏覽器, ?返回結(jié)果為js代碼, js代碼的內(nèi)容是函數(shù)調(diào)用的形式, ?函數(shù)名為callback 的值, 函數(shù)的參數(shù)為之前要返回的json對象, 瀏覽器就可以執(zhí)行之前聲明 的這個回調(diào)函數(shù), 對返回的數(shù)據(jù)進行操作;

    • 相當(dāng)于向http://localhost:3000/say?wd=Iloveyou&callback=show這個地址請求數(shù)據(jù),然后后臺返回show('你好么'),最后會運行show()這個函數(shù),打印出'你好么'


      spacer.gif

    • ajax屬于同源策略, ?jsonp屬于非同源策略; ?

    • ajax的核心是通過XmlHttpRequest獲取非本頁內(nèi)容,而jsonp的核心則是動態(tài)添加<script>標(biāo)簽來調(diào)用服務(wù)器提供的js腳本。

    • 普通的ajax請求發(fā)出去的類型是 xhr, jsonp 請求發(fā)出去的類型是script, ajax請求返回的數(shù)據(jù)類型是json, ?jsonp返回類型是 js腳本; ?

    產(chǎn)生跨域后解決

    解決思路:

    方式:

    一. 從被調(diào)用方考慮,有三種情況,分別是服務(wù)器實現(xiàn) (重點),nginx配置apache配置。

    原理: 在這種解決方案里面, 跨域請求是直接從調(diào)用方的瀏覽器發(fā)送到被調(diào)用方的http服務(wù)器, http服務(wù)器再把請求轉(zhuǎn)發(fā)到應(yīng)用服務(wù)器; 應(yīng)用服務(wù)器處理完之后, 把響應(yīng)返回給http服務(wù)器, http服務(wù)器再把響應(yīng)轉(zhuǎn)回到調(diào)用方的瀏覽器;

    最終的目標(biāo)是要在響應(yīng)頭里添加字段, 所以這里有兩個地方可以增加響應(yīng)頭; 一個是中間的http服務(wù)器上增加, 也就是Nginx/ Apache; 一個是應(yīng)用服務(wù)器, 也就是Tomcat


    spacer.gif


    • 被調(diào)用方; 基于讓被調(diào)用方支持跨域的思路 , 支持基于http協(xié)議關(guān)于跨域方面的要求; ?也就是從A域名調(diào)用b域名的時候, 在b域名返回的響應(yīng)頭里添加指定字段, 告訴瀏覽器, 我允許A域名調(diào)用, 瀏覽器通過校驗, 就不會報跨域錯誤;

    • 調(diào)用方; 如果被調(diào)用方不是公司的, 無法進行修改, 就可以從調(diào)用方進行修改, 這種做法是隱藏跨域, 通過一個代理, 從瀏覽器里發(fā)出的都是A域名的請求, 通過這個代理把指定的url轉(zhuǎn)到B域名里, 在瀏覽器看來它們就是同一個域名, 就沒有跨域問題

    1. 被調(diào)用方解決: CORS

      CORS 需要瀏覽器和后端同時支持。IE 8 和 9 需要通過 XDomainRequest 來實現(xiàn)。

      瀏覽器會自動進行 CORS 通信,實現(xiàn) CORS 通信的關(guān)鍵是后端;

      服務(wù)端設(shè)置 Access-Control-Allow-Origin 就可以開啟 CORS;

    瀏覽器在發(fā)送跨域請求時, 會先判斷請求是簡單請求和非簡單請求。 簡單請求是先執(zhí)行請求再驗證,非簡單請求是先驗證再請求。 非簡單請求實際上會發(fā)送兩個請求, 第一次會先發(fā)送一個預(yù)檢請求, 這個預(yù)檢請求是瀏覽器額外發(fā)送的 options 預(yù)檢請求, ?檢查通過之后, 才會真正把跨域請求發(fā)送出去;

    預(yù)檢命令的緩存: 非簡單請求中添加的響應(yīng)頭, 用于緩存預(yù)檢命令, 提高請求效率; 告訴瀏覽器在一個小時之內(nèi)可以緩存預(yù)檢命令的結(jié)果, 發(fā)送非簡單請求時不用再發(fā)送預(yù)檢命令 ?res.setHeader('Access-Control-Max-Age', 3600)

    spacer.gif

    簡單請求(比較常見):

    • 方法為 get,head,post 中的一種;

    • 請求header里面沒有自定義頭;

    • Content-Type的值為限于以下3者之一: ?text/plain, multipart/form-data, application/x-www-form-urlencoded


    非簡單請求(比較常見):

    • put, delect方法的ajax請求;

    • 發(fā)送json格式的ajax請求;

    • 帶自定義頭的ajax請求。

    簡單請求處理方案:在響應(yīng)頭中添加 ? ? ?

    **Access-Control-Allow-Origin=“允許跨域的url”**,即跨省域時,請求頭Origin的值,所以一般是獲取Origin的值。
    
    **Access-Control-Allow-Method=“*”**,允許的方法。

    非簡單請求處理方案:響應(yīng)頭中添加

    "*"?表示允許所有內(nèi)容或類型;?
    Access-Control-Allow-Origin=“允許跨域的url”,即跨域時,可以獲取請求頭Origin的值。
    
    Access-Control-Allow-Method=“*”,//?允許所有方法
    'Access-Control-Allow-Origin',?*?//?允許所有域?????
    
    res.setHeader('Access-Control-Request-Headers',?'Content-Type')
    Access-Control-Request-Headers=“Content-Type"?//?自定義的header的key?
    
    如:?
    ?//?設(shè)置哪個域/?源可以跨域調(diào)用
    ????res.setHeader('Access-Control-Allow-Origin',?origin)
    ????//?允許攜帶哪個頭?可以跨域
    ????res.setHeader('Access-Control-Allow-Headers',?'name')
    ????//?允許哪個方法?可以跨域
    ????res.setHeader('Access-Control-Allow-Methods',?'PUT')
    ????//?允許攜帶cookie
    ????res.setHeader('Access-Control-Allow-Credentials',?true)
    ????
    //?預(yù)檢命令的緩存時間;?用于緩存預(yù)檢命令,?提高請求效率;?告訴瀏覽器在一個小時之內(nèi)可以緩存這段信息,?發(fā)送非簡單請求時不用再發(fā)送預(yù)檢命令
    ????res.setHeader('Access-Control-Max-Age',?3600)
    
    ????//?允許返回的頭
    ????res.setHeader('Access-Control-Expose-Headers',?'name')

    帶cookies的跨域解決:在響應(yīng)頭添加

    1) 帶cookie的時候, origin 必須是全匹配, 不能使用*, 否則會報錯, 并且要添加 Access-Control-Allow-Credentials="true" 的字段;

    res.setHeader('Access-Control-Allow-Origin',?"http://locahost:?8081")
    
    Access-Control-Allow-Credentials="true"??//??允許發(fā)送請求時攜帶cookies

    http里的會話, 也就是session, 是依賴于cookie的, sessionid存放在cookie中, 在實際工作中, 帶cookie的跨域很重要;

    2) 用 filter實現(xiàn)解決: 瀏覽器發(fā)現(xiàn)請求是跨域的時候, 會在請求頭里添加origin字段, 這個字段有當(dāng)前域的信息, 后臺可以在filter里得到這個字段, 然后再把它寫回到 Access-Control-Allow-Origin 里面, 這樣就可以支持所有域的調(diào)用;

    spacer.gif

    spacer.gif

    帶自定義頭的跨域

    在jQuery里面, 設(shè)置自定義頭有兩種方法:

    1) 在headers里添加;

    2) XMLHttpRequest 對象提供了一個設(shè)置請求頭的方法: setRequestHeader, 可以在 beforeSend 回調(diào)函數(shù)里用xhr.setRequestHeader("x-header2":, "aaa") 方法設(shè)置;

    spacer.gif

    spacer.gif

    請求頭里的自定義屬性:

    spacer.gif


    獲取請求頭的自定義屬性 , 然后再把它寫到響應(yīng)頭的 Access-Control-Allow-Origin 里面 , 就可以支持所有自定義頭

    spacer.gif


    nodejs可以引入第三方包cors

    npm?install?--save?cors
    //CORS?middleware
    var?allowCrossDomain?=?function(req,?res,?next)?{
    ????res.header('Access-Control-Allow-Origin',?'http://example.com');
    ????res.header('Access-Control-Allow-Methods',?'GET,PUT,POST,DELETE');
    ????res.header('Access-Control-Allow-Headers',?'Content-Type');
    
    ????next();
    }
    
    //...
    app.configure(function()?{
    ????app.use(express.bodyParser());
    ????app.use(express.cookieParser());
    ????app.use(express.session({?secret:?'cool?beans'?}));
    ????app.use(express.methodOverride());
    ????app.use(allowCrossDomain);
    ????app.use(app.router);
    ????app.use(express.static(__dirname?+?'/public'));
    });


    1. 被調(diào)用方解決: ngnix反向代理配置 實現(xiàn)跨域(proxy_pass模塊):

    虛擬主機: 多個域名指向同一個服務(wù)器, 服務(wù)器根據(jù)不同的域名把請求轉(zhuǎn)到不同的應(yīng)用服務(wù)器, 看上去好像有多個主機, 實際上只有一個主機;

    server{
    ??#?監(jiān)聽9099端口
    ??listen?9099;
    ??#?域名是localhost
    ??server_name?localhost;
    ??#凡是localhost:9099/api這個樣子的,都轉(zhuǎn)發(fā)到真正的服務(wù)端地址http://localhost:9871
    ??location?^~?/api?{
    ??????proxy_pass?http://localhost:9871;
    ??}
    }

    spacer.gif

    5bbca2b3000190d805000227.jpg

    1. 被調(diào)用方- Apache解決

    和 Nginx作用是一樣的, ?做法就是把Nginx上的配置再實現(xiàn)一次;

    spacer.gif


    Vue中 webpack.config.js里面配置devServer的proxy

    利用node + webpack + webpack-dev-server代理接口跨域。在開發(fā)環(huán)境下,由于vue渲染服務(wù)和接口代理服務(wù)都是webpack-dev-server同一個,所以頁面與代理接口之間不再跨域,無須設(shè)置headers跨域信息了。后臺可以不做任何處理。

    module.exports?=?{
    ??entry:?{},
    ??module:?{},
    ??...
    ??devServer:?{
    ??????historyApiFallback:?true,
    ??????proxy:?[{
    ??????????context:?'/login',
    ??????????target:?'http://www.daxihong.com:8080',??//?代理跨域目標(biāo)接口
    ??????????changeOrigin:?true,
    ??????????secure:?false,??//?當(dāng)代理某些https服務(wù)報錯時用
    ??????????cookieDomainRewrite:?'www.daxihong.com'??//?可以為false,表示不修改
    ??????}],
    ??????noInfo:?true
    ??}
    }

    谷歌的插件allow cors可以解決谷歌瀏覽器里面的跨域

    webSocket本身不存在跨域的問題, ?所以我們可以利用webSocket來進行非同源中間的通信


    查看全部
  • http://img1.sycdn.imooc.com//5d737a0d00019e4910990906.jpg

    http://img1.sycdn.imooc.com//5d737a5b000163b614980533.jpg

    經(jīng)過創(chuàng)建的 過濾器的過濾操作后,filter 解決 了 瀏覽器對跨域請求的攔截,當(dāng)有多個地址需要進行相同操作時,可以使用"*"代替具體的地址,從而實現(xiàn)大范圍的跨域請求

    查看全部
  • 解決跨域問題①:

    針對該瀏覽器添加參數(shù),禁止瀏覽器做校驗,避免報跨域問題


    http://img1.sycdn.imooc.com//5d736d8c0001891313320740.jpg
    查看全部
  • 修改瀏覽器的設(shè)置后,沒有再出現(xiàn)跨域問題

    由此可以認(rèn)為,跨域問題主要還是在瀏覽器發(fā)生的校驗失敗等問題導(dǎo)致的,與后臺沒有任何關(guān)系

    http://img1.sycdn.imooc.com//5d736d0300010dc009560579.jpg

    查看全部
  • 發(fā)生Ajax 跨域請求的原因

    查看全部
  • Ajax 跨域請求 限制原因:

    3、XHR(XMLHttpRequest)請求:

    http://img1.sycdn.imooc.com//5d7343f00001d4e716000783.jpg

    測試: 新增加一個 <img>標(biāo)簽,重啟啟動后,由圖可知,盡管新添加了一個 <img>標(biāo)簽,但是,瀏覽器所報的錯誤還是只有一個,而這一個便是之前的<a>標(biāo)簽的請求;而這是由于 <img> 和 <a> 兩個請求發(fā)送時的 Type 不同,<img> 是json類型的,而<a>則是xhr類型的

    查看全部
  • Ajax 跨域請求 限制原因:

    2、跨域:

    http://img1.sycdn.imooc.com//5d7341660001c07209650571.jpg

    由圖中可知,server? 和 client 的 port 端口是不同的,因此,瀏覽器檢測到后認(rèn)為其發(fā)生了跨域

    查看全部
  • Ajax 跨域請求 限制原因:

    1、瀏覽器限制:

    http://img1.sycdn.imooc.com//5d733c800001341412930877.jpg

    由圖中可以知道,當(dāng)發(fā)送請求時,盡管控制臺報了跨域請求錯誤,但是IDE的服務(wù)器后臺,依舊正常收到了請求,并打印相關(guān) 響應(yīng)字段

    查看全部
  • Ajax 跨域請求 限制原因:

    1、瀏覽器限制:

    http://img1.sycdn.imooc.com//5d733c3300011b7712910975.jpg

    由截圖可知,服務(wù)器的請求響應(yīng)狀態(tài)為200,這代表這客戶端的請求被服務(wù)器正常的響應(yīng)了,服務(wù)器后臺是沒有任何限制,而且正確處理 了;從側(cè)面也就證明了是 瀏覽器進行了限制,從而報了錯誤給我們

    查看全部
  • http://img1.sycdn.imooc.com//5d733994000193ed14700568.jpg

    引入jasmine 測試框架后,console 會生成一個界面用于提示用戶測試結(jié)果及相關(guān)錯誤

    查看全部
  • http://img1.sycdn.imooc.com//5d7333ab0001cc1a10410596.jpg

    http://img1.sycdn.imooc.com//5d7333ac000125b512490632.jpg

    http://img1.sycdn.imooc.com//5d7333ac0001b3fa09530605.jpg

    引入前端測試框架 jasmine,提高開發(fā)效率,從官網(wǎng)進入到 Releases目錄下下載 jasmine .zip 壓縮文件,解壓后將lib目錄下的包復(fù)制到工程項目的static目錄下

    查看全部
  • 引入 jasmine 測試框架

    查看全部
  • 創(chuàng)建 ajaxClient 工程并編寫 前臺頁面代碼

    查看全部

舉報

0/150
提交
取消
課程須知
需要具備基本的前后臺開發(fā)技術(shù)
老師告訴你能學(xué)到什么?
AJAX跨域產(chǎn)生的原因和解決思路 系統(tǒng)的基本部署架構(gòu)和跨域的關(guān)系 http服務(wù)器nginx和apache的重要作用和跨域的2種解決思路 jsonp的工作機制和優(yōu)缺點 前臺測試框架Jasmine的使用

微信掃碼,參與3人拼團

微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

友情提示:

您好,此課程屬于遷移課程,您已購買該課程,無需重復(fù)購買,感謝您對慕課網(wǎng)的支持!