百度ueditor富文本 單圖上傳iframe跨域問題

最近在使用百度ueditor富文本編輯器拌屏,由于是一個(gè)前后端分離的項(xiàng)目肋层,并且需要使用單圖上傳的功能塘匣,所以不可避免的會(huì)產(chǎn)生跨域問題蛉鹿,先來看看官方給的說法:

    單圖上傳暫時(shí)不支持跨域設(shè)置齐媒,為了兼容低版本瀏覽器蒲每,使用了提交表單到iframe提交。通過iframe的onload事件喻括,觸發(fā)回調(diào)函數(shù)邀杏,這時(shí)候再讀取iframe里面的內(nèi)容,得到的服務(wù)器返回?cái)?shù)據(jù)唬血。 跨域情況下望蜡,產(chǎn)生了跨域的iframe訪問,可以解決方法都需要前后端一起改變拷恨。要解決這個(gè)問題泣特,小伙伴們發(fā)揮想象力吧。

可以說相當(dāng)?shù)牟回?fù)責(zé)任了哈哈挑随,先不吐槽這個(gè)状您。

首先來看看問題是怎么產(chǎn)生的,谷歌chrome下配置好ueditor之后直接點(diǎn)擊單圖上傳勒叠,沒有任何反應(yīng),別急膏孟,看一眼Network

image

可以看到服務(wù)器有返回信息眯分,但為什么編輯器中沒有回顯成功呢?

我們定位到ueditor.all.js這個(gè)文件柒桑,看看單圖上傳時(shí)都做了些什么
定位到這一段代碼(在24500行左右弊决,我的源文件修改過了,可能有所不同)

domUtils.on(input, 'change', function(){
    if(!input.value) return;
    var loadingId = 'loading_' + (+new Date()).toString(36);
    var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';

    var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));   2
    var allowFiles = me.getOpt('imageAllowFiles');

    me.focus();
    me.execCommand('inserthtml', '<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme +'/images/spacer.gif" title="' + (me.getLang('simpleupload.loading') || '') + '" >');

    function callback(){
        try{
            var link, json, loader,
                body = (iframe.contentDocument || iframe.contentWindow.document).body,
                result = body.innerText || body.textContent || '';
            json = (new Function("return " + result))();

            link = me.options.imageUrlPrefix + json.url;
            if(json.state == 'SUCCESS' && json.url) {
                loader = me.document.getElementById(loadingId);
                loader.setAttribute('src', link);
                loader.setAttribute('_src', link);
                loader.setAttribute('title', json.title || '');
                loader.setAttribute('alt', json.original || '');
                loader.removeAttribute('id');
                domUtils.removeClasses(loader, 'loadingclass');
            } else {
                showErrorLoader && showErrorLoader(json.state);
            }
        }catch(er){
            showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));
        }
        form.reset();
        domUtils.un(iframe, 'load', callback);
    }
    function showErrorLoader(title){
        if(loadingId) {
            var loader = me.document.getElementById(loadingId);
            loader && domUtils.remove(loader);
            me.fireEvent('showmessage', {
                'id': loadingId,
                'content': title,
                'type': 'error',
                'timeout': 4000
            });
        }
    }

    /* 判斷后端配置是否沒有加載成功 */
    if (!me.getOpt('imageActionName')) {
        console.log(1)
        errorHandler(me.getLang('autoupload.errorLoadConfig'));
        return;
    }
    // 判斷文件格式是否錯(cuò)誤
    var filename = input.value,
        fileext = filename ? filename.substr(filename.lastIndexOf('.')):'';
    if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
        console.log(2)
        showErrorLoader(me.getLang('simpleupload.exceedTypeError'));
        return;
    }

    domUtils.on(iframe, 'load', callback);
    form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params);
    form.submit();
});

可以看到有一個(gè)try魁淳,catch語(yǔ)句飘诗,正是在這里出現(xiàn)了跨域錯(cuò)誤

console.log((iframe.contentDocument || iframe.contentWindow.document).body);
try{
    var link, json, loader,                          
        body = (iframe.contentDocument || iframe.contentWindow.document).body,
        result = body.innerText || body.textContent || '';
    json = (new Function("return " + result))();

    link = me.options.imageUrlPrefix + json.url;
    if(json.state == 'SUCCESS' && json.url) {
        loader = me.document.getElementById(loadingId);
        loader.setAttribute('src', link);
        loader.setAttribute('_src', link);
        loader.setAttribute('title', json.title || '');
        loader.setAttribute('alt', json.original || '');
        loader.removeAttribute('id');
        domUtils.removeClasses(loader, 'loadingclass');
    } else {
        showErrorLoader && showErrorLoader(json.state);
    }
}catch(er){
    showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));
}

隨便console一下,出現(xiàn)如下報(bào)錯(cuò)

Uncaught DOMException: Blocked a frame with origin "###" from accessing a cross-origin frame.at HTMLIFrameElement.callback (###)界逛。

image

這個(gè)其實(shí)就是游覽器出于安全考慮昆稿,禁止iframe跨域訪問,而官方也說了:

image

那么怎么解決iframe跨域的問題呢息拜,找到了問題所在溉潭,解決起來就簡(jiǎn)單了,我試了兩種方法少欺,介紹一下:

第一種喳瓣,使用new FormData()來提交;

除開不兼容ie9及以下版本之外赞别,幾乎是最好用的畏陕,廢話不多說,直接貼代碼仿滔;直接替換掉上文的那一段源文件代碼就ok

domUtils.on(input, 'change', function() {
    if(!input.value) return;
    var loadingId = 'loading_' + (+new Date()).toString(36);
    var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));
    var allowFiles = me.getOpt('imageAllowFiles');

    me.focus();
    me.execCommand('inserthtml', '<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme +'/images/spacer.gif" title="' + (me.getLang('simpleupload.loading') || '') + '" >');

    //!* 判斷后端配置是否沒有加載成功 *!/
    if (!me.getOpt('imageActionName')) {
    console.log(11)
        errorHandler(me.getLang('autoupload.errorLoadConfig'));
        return;
    }
    // 判斷文件格式是否錯(cuò)誤
    var filename = input.value,
        fileext = filename ? filename.substr(filename.lastIndexOf('.')):'';
    if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
        showErrorLoader(me.getLang('simpleupload.exceedTypeError'));
        return;
    }

    var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';
    var action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?' : '&') + params);
    var formData = new FormData();
    formData.append("upfile", form[0].files[0] );
    $.ajax({
        url: action,
        type: 'POST',
        cache: false,
        data: formData,
        processData: false,
        contentType: false,
        success: function (data) {
        data = JSON.parse(data);
        var link, loader,
            body = (iframe.contentDocument || iframe.contentWindow.document).body,
            result = body.innerText || body.textContent || '';
        link = me.options.imageUrlPrefix + data.url;
        if(data.state == 'SUCCESS' && data.url) {
            loader = me.document.getElementById(loadingId);
            loader.setAttribute('src', link);
            loader.setAttribute('_src', link);
            loader.setAttribute('title', data.title || '');
            loader.setAttribute('alt', data.original || '');
            loader.removeAttribute('id');
            domUtils.removeClasses(loader, 'loadingclass');
        } else {
            showErrorLoader && showErrorLoader(data.state);
        }
        form.reset();
        }
    });
    function showErrorLoader(title){
        if(loadingId) {
        var loader = me.document.getElementById(loadingId);
        loader && domUtils.remove(loader);
        me.fireEvent('showmessage', {
            'id': loadingId,
            'content': title,
            'type': 'error',
            'timeout': 4000
        });
        }
    }
});

第二種方式 依然使用iframe來進(jìn)行提交

為什么還要使用iframe蹭秋,因?yàn)槲覀兊膇e(6~9)不支持new FormData(),那就還得從iframe這種方式入手,官方也提到了從iframe入手其實(shí)也可以解決:跨域情況下堤撵,產(chǎn)生了跨域的iframe訪問仁讨,可以解決方法都需要前后端一起改變。要解決這個(gè)問題实昨,小伙伴們發(fā)揮想象力吧洞豁。
跨域情況下,其實(shí)是無法訪問iframe內(nèi)的body內(nèi)容的荒给,也就是圖片可以上傳到后臺(tái)丈挟,但是前端無法獲取回調(diào)信息,也就是說正常途徑下志电,前端無法實(shí)現(xiàn)回顯曙咽。
那么解決思路就來了,既然是由iframe跨域產(chǎn)生的問題挑辆,那我們就可以從iframe跨域入手例朱,后端處理這條請(qǐng)求后孝情,重定向至前端的一個(gè)空html頁(yè)面,將所有的回調(diào)參數(shù)放到url中~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末洒嗤,一起剝皮案震驚了整個(gè)濱河市箫荡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渔隶,老刑警劉巖羔挡,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異间唉,居然都是意外死亡绞灼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門呈野,熙熙樓的掌柜王于貴愁眉苦臉地迎上來低矮,“玉大人,你說我怎么就攤上這事际跪∩谭穑” “怎么了喉钢?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵姆打,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我肠虽,道長(zhǎng)幔戏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任税课,我火速辦了婚禮闲延,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘韩玩。我一直安慰自己垒玲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布找颓。 她就那樣靜靜地躺著合愈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪击狮。 梳的紋絲不亂的頭發(fā)上佛析,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音彪蓬,去河邊找鬼寸莫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛档冬,可吹牛的內(nèi)容都是我干的膘茎。 我是一名探鬼主播桃纯,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼辽狈!你這毒婦竟也來了慈参?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刮萌,失蹤者是張志新(化名)和其女友劉穎驮配,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體着茸,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壮锻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涮阔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猜绣。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖敬特,靈堂內(nèi)的尸體忽然破棺而出掰邢,到底是詐尸還是另有隱情,我是刑警寧澤伟阔,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布辣之,位于F島的核電站,受9級(jí)特大地震影響皱炉,放射性物質(zhì)發(fā)生泄漏怀估。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一合搅、第九天 我趴在偏房一處隱蔽的房頂上張望多搀。 院中可真熱鬧,春花似錦灾部、人聲如沸康铭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)从藤。三九已至,卻和暖如春春弥,著一層夾襖步出監(jiān)牢的瞬間呛哟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工匿沛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扫责,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓逃呼,卻偏偏與公主長(zhǎng)得像鳖孤,于是被迫代替她去往敵國(guó)和親者娱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1苏揣、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_X自主閱讀 15,979評(píng)論 3 119
  • 在這家熙熙攘攘的快餐廳突然想寫點(diǎn)什么黄鳍。 誠(chéng)如我面前這盤蛋炒飯一樣,總有些蛋是糊的平匈,但是吃起來咯嘣脆框沟。 誠(chéng)如這可樂里...
    颶飔閱讀 187評(píng)論 0 0
  • 發(fā)幾張前幾天練習(xí)的寫意牡丹,顏色調(diào)的不理想增炭,繼續(xù)努力忍燥!
    綠色的石頭閱讀 402評(píng)論 2 7
  • 四、要有個(gè)活地圖隙姿。 指揮員和參謀必須熟悉地圖梅垄,要經(jīng)常讀地圖。熟讀地圖可以產(chǎn)生見解输玷,產(chǎn)生智慧队丝,產(chǎn)生辦法,產(chǎn)生信心...
    次第花開1583閱讀 510評(píng)論 0 0
  • 娟子多年不見的同事某天突然造訪吞加,這個(gè)同事上班期間并沒有多少交往裙犹,說過得話都寥寥無幾尽狠,這么多年過去了,只剩下一個(gè)有點(diǎn)...
    紅色大喇叭花閱讀 2,309評(píng)論 36 34