Ajax與彈窗被瀏覽器攔截(windows.open)的問題

? ? ? ? 最近在項目中有這樣一個需求:在前端頁面的js文件中從后臺獲取一個URL,拿到URL后調(diào)用windows.open方法打開這個URL。URL由后端程序拼接而成,在開發(fā)過程中遇到了兩個問題,前端js代碼如下:

 showWindow : function() {
                Fw.Ajax.request({
                    url : '/ebank/callCenter.do',
                    params : {'COMPY_NAME':COMPY_NAME},
                    page : false,
                    success : function(data) {
                        callCenterUrl = data.call_center_url;   
                    },  
                    if(callCenterUrl != null) {
                        window.open(callCenterUrl,'_blank','width=850, height=600, resizable=yes, toolbar=no, menubar=no');                                             
                        }else {
                            alert("客服系統(tǒng)繁忙,請稍后再試");
                        }               
                    onFailure : function() {
                    },                  
                });         
        },

1.可能出現(xiàn)先彈出窗口,后拿到URL的情況

  • 上面代碼經(jīng)常出現(xiàn)打開空白頁面的結(jié)果,分析原因是Ajax異步請求后端,還沒拿到URL就執(zhí)行了windows.open方法導(dǎo)致打開了空白頁(URL初始值賦的“_blank”)
  • 嘗試解決了一下,將彈窗邏輯放在回調(diào)函數(shù)success中,確實可以保證先拿到URL后再執(zhí)行windows.open方法,但是又引出了一個新的問題。

2.瀏覽器攔截彈窗問題

  • 將彈窗邏輯放入Ajax的回調(diào)函數(shù)success中后,彈出窗口在IE瀏覽器遭到攔截:
    ? ? ? ?其原因是瀏覽器出于安全策略阻擋了非用戶點擊彈出的窗口,所謂非用戶點擊就是彈出的窗口不是直接由用戶點擊事件觸發(fā)的彈窗。在這段邏輯當(dāng)中,彈窗事件由程序發(fā)起,所以會被瀏覽器攔截。然而對于用戶來說這種體驗肯定是不好的,你不能指望一個用戶對瀏覽器以及程序了如指掌。于是通過搜索找到一種解決方法,更新后的代碼如下:
showWindow : function() {
            //先打開窗口,防止放進(jìn)Ajax中被瀏覽器攔截
            var adPopup = window.open(callCenterUrl,'_blank','width=850, height=600, resizable=yes, toolbar=no, menubar=no');
                Fw.Ajax.request({
                    url : '/ebank/callCenter.do',
                    params : {'COMPY_NAME':COMPY_NAME},
                    page : false,
                    success : function(data) {
                        callCenterUrl = data.call_center_url;   
                        if(callCenterUrl != null) {
                            //避免被瀏覽器攔截,重定向窗口
                            adPopup.location = callCenterUrl;   
                        }else {
                            alert("客服系統(tǒng)繁忙,請稍后再試");
                        }
                    },  
                    
                    onFailure : function() {
                    },                  
                });         
        },
  • 上述JS代碼將打開窗口動作放在了監(jiān)聽按鈕點擊事件下,在Ajax函數(shù)執(zhí)行之前,我在項目本地加了一個loading動畫的頁面,在拿到真正后臺傳來的URL之前,彈出的窗口都會在這個Loading頁面等待。一旦Ajax返回了真正的URL,再將窗口重定向到新的URL。經(jīng)過這種設(shè)置,成功解決了彈窗被瀏覽器攔截的問題。

3.對Ajax的好奇與初步探索

  • Ajax是什么
    AJAX is not a programming language. It is just a technique for creating better and more interactive web applications.
    AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
    AJAX 不是新的編程語言,而是一種使用現(xiàn)有標(biāo)準(zhǔn)的新方法。
    AJAX 是與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁的藝術(shù),在不重新加載整個頁面的情況下刷新局部頁面。
  • Ajax怎么實現(xiàn)的
    • 實際使用了幾次Ajax與后臺進(jìn)行交互后,我不禁在想,這么好用的技術(shù)是怎么實現(xiàn)的?初步猜測是另起了一個線程,在子線程里進(jìn)行操作,然后在子線程里對局部頁面進(jìn)行更新。
    • 經(jīng)過搜索,得知Ajax請求的核心是XMLHttpRequest ,原來整個Ajax與后臺交互與刷新局部頁面的技術(shù)是這個對象。對于XMLHttpRequest的介紹有很多,這里僅貼Ajax實現(xiàn)封裝以輔助自己記憶。代碼來自 AJAX的實現(xiàn)原理以及封裝
var $={
    /*傳遞參數(shù)對象,返回拼接之后的字符串*/
    /*{‘name’:’jack,’age’:20}=>  name=jack&age=20&*/
    getParmeter:function(data){
        var result="";
        for(var key in data){
            result=result+key+"="+data[key]+"&";
        }
        /*將結(jié)果最后多余的&截取掉*/
        return result.slice(0,-1);
    },
    /*實現(xiàn)ajax請求*/
    ajax:function(obj){
        /*1.判斷有沒有傳遞參數(shù),同時參數(shù)是否是一個對象*/
        if(obj==null || typeof obj!="object"){
            return false;
        }
        /*2.獲取請求類型,如果沒有傳遞請求方式,那么默認(rèn)為get*/
        var type=obj.type || 'get';
        /*3.獲取請求的url  location.pathname:就是指當(dāng)前請求發(fā)起的路徑*/
        var url=obj.url || location.pathname;
        /*4.獲取請求傳遞的參數(shù)*/
        var data=obj.data || {};
        /*4.1獲取拼接之后的參數(shù)*/
        data=this.getParmeter(data);
        /*5.獲取請求傳遞的回調(diào)函數(shù)*/
        var success=obj.success || function(){};

        /*6:開始發(fā)起異步請求*/
        /*6.1:創(chuàng)建異步對象*/
        var xhr=new XMLHttpRequest();
        /*6.2:設(shè)置請求行,判斷請求類型,以此決定是否需要拼接參數(shù)到url*/
        if(type=='get'){
            url=url+"?"+data;
            /*重置參數(shù),為post請求簡化處理*/
            data=null;
        }
        xhr.open(type,url);
        /*6.2:設(shè)置請求頭:判斷請求方式,如果是post則進(jìn)行設(shè)置*/
        if(type=="post"){
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        }
        /*6.3:設(shè)置請求體,post請求則需要傳遞參數(shù)*/
        xhr.send(data);

        /*7.處理響應(yīng)*/
        xhr.onreadystatechange=function(){
            /*8.判斷響應(yīng)是否成功*/
            if(xhr.status==200 && xhr.readyState==4){
                /*客戶端可用的響應(yīng)結(jié)果*/
                var result=null;
                /*9.獲取響應(yīng)頭Content-Type ---類型是字符串*/
                var grc=xhr.getResponseHeader("Content-Type");
                /*10.根據(jù)Content-Type類型來判斷如何進(jìn)行解析*/
                if(grc.indexOf("json") != -1){
                    /*轉(zhuǎn)換為js對象*/
                    result=JSON.parse(xhr.responseText);
                }
                else if(grc.indexOf("xml") != -1){
                    result=xhr.responseXML;
                }
                else{
                    result=xhr.responseText;
                }
                /*11.拿到數(shù)據(jù),調(diào)用客戶端傳遞過來的回調(diào)函數(shù)*/
                success(result);
            }
        }

    }
};

調(diào)用方式與jquery類似的:
$.ajax({
    url:'',
    type:'',
    data: {},
    success:function(result){
        //code...
    }
});
  • Ajax出現(xiàn)已經(jīng)有近20歷史,是否有替代技術(shù)?
    • 通過我的搜索,發(fā)現(xiàn)了一個傳說中將會取代Ajax的技術(shù),叫做Fetch,當(dāng)然了,具體能不能取代Ajax可能還要繼續(xù)觀察,但是對于這技術(shù)了解一下總是好的。
  • 引用W3C School的一段話:十多年來,XMLHttpRequest 對象一直被 AJAX 操作所接受,但是我們知道,XMLHttpRequest 對象的 API 設(shè)計并不是很好,輸入、輸出、狀態(tài)都在同一個接口管理,容易寫出非常混亂的代碼。那么Fetch API就應(yīng)勢而生,提供了一種新規(guī)范,用來取代善不完美的 XMLHttpRequest 對象。
    Fetch API 主要有兩個特點:一是接口合理化,AJAX 是將所有不同性質(zhì)的接口都放在 XHR 對象上,而Fetch是將它們分散在幾個不同的對象上,設(shè)計更合理;二是Fetch操作返回 Promise 對象,避免了嵌套的回調(diào)函數(shù)。
    接下來將花點時間學(xué)習(xí)一下Fetch,先附上Fetch API官方文檔。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,825評論 1 45
  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,211評論 3 119
  • 有一天下午,小明在樓下玩,樹上有一只小鳥在學(xué)飛,一不小心掉在樹樁上,被小明抓住了,小明拿來一根繩子,拴住小鳥的...
    謝晨俊閱讀 323評論 0 0
  • 秋天的景色,是如此凄美和蕭條。 天已近黃昏,惟有幾棵老樹屹立于此。樹桿上刻著時間的印記,樹葉也無影無蹤了。唯有那枯...
    qqyzyylwmdqc閱讀 194評論 0 0
  • 小梅絕對是個美人。高挑、豐滿、嫵媚,脾氣好、與世無爭,是個爛好人,任何人都能和她融洽相處。 小梅和老公大偉在同一個...
    小玩具媽媽閱讀 3,347評論 86 75

友情鏈接更多精彩內(nèi)容