使用nodejs將第三方需要登錄的頁面嵌入到系統(tǒng)中

使用nodejs將第三方頁面嵌入到系統(tǒng)中

最近在公司遇到一個特殊的需求,需要將第三方的頁面嵌入到系統(tǒng)中仅孩,并更改內部的樣式菜职。


如何將外來的頁面嵌入到系統(tǒng)中?

百度查找了各路大神的方案肉微,得出結論:js不允許訪問不同源iframe內的元素匾鸥。所以解決方案只能寫一個后臺來搞定這件事情。當時想寫java后臺碉纳,后面想想部署等相對復雜勿负,最終使用了強大的nodejs。

首先嘗試前端js能不能獲取到不同源的iframe內的dom元素劳曹。

tip:試了才知道奴愉,映象才深刻。話不多說直接上代碼铁孵。

html

<div class="col-xl-3">
    <button>刪除</button>
</div>
<div class="col-xl-9">
    <!--不同源的百度頁面-->
    <iframe  width="100%" height="800px" src="http://www.baidu.com"></iframe>
    <!--同源的百度頁面-->
    <!--<iframe width="100%" height="800px" src="/baidu"></iframe>-->
</div>

js

//點擊按鈕就將百度頁面頭和大logo去掉
$('button').click(function () {
    var $iframe=$('iframe');
    $iframe.contents().find('head').remove();
    $iframe.contents().find('#lg').remove();
});

結果是點擊了沒有任何反應锭硼。

使用nodejs中轉頁面

使用express做接口,使用superagent做頁面的請求库菲。
routes代碼如下:

var express = require('express');
var router = express.Router();
var path = require('path');
//使用agent自動處理cookie
const agent = require('superagent').agent();

router
    .get('/', function(req, res, next) {
      res.sendFile(path.join(__dirname, '../html', 'iframe.html'));
    })
    .get('/baidu',(req,res) => {
      agent.get('http://www.baidu.com',(areq,ares) => {
        res.end(ares.text);
      })
    });

module.exports = router;

當請求/baidu時agent會先將頁面請求下來然后再返回給頁面账忘,這樣就簡單地處理了一個不同源問題。

我們修改html的內容,如下:

<div class="col-xl-9">
    <!--不同源的百度頁面-->
    <!--<iframe  width="100%" height="800px" src="http://www.baidu.com"></iframe>-->
    <!--同源的百度頁面-->
    <iframe width="100%" height="800px" src="/baidu"></iframe>
</div>

再次打開鳖擒,點擊刪除按鈕頁面的head和lg成功被刪除溉浙。


image

至此可以使用nodejs來解決這個問題。最后貼上實際代碼蒋荚。

js

'use strict';
// 要代理的url
const proxyUri = 'http://xxx.xxx.xxx';

var express = require('express');
var cookie = require('cookie-parser');
var events = require('events');
//本來想在nodejs中處理dom的
var cheerio = require('cheerio');
const superAgent = require('superagent');
const httpProxy = require('http-proxy');

var router = express.Router();

router.use(cookie());
const agent = superAgent.agent(express);

var emitter = new events.EventEmitter();
emitter.on("setCookeie", cookieReset);

let proxy = httpProxy.createProxyServer({
    target: proxyUri,
    changeOrigin: true,
    cookieDomainRewrite: {
        '*': proxyUri
    },
    secure: false,
});

proxy.on('error', function (err, request, response) {
    response.writeHead(500, {
        'Content-Type': 'text/plain',
    });
    console.log(err);
    response.end('server error');
});

//設置跨域訪問
router.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Credentials', true);
    next();
});
router.use(express.static('../static/'));


login();

/**
 * 登錄獲取cookie
 */
function login(isFlag) {
    agent
        .post('http://xxx.xxx.xxx/login')
        .type('form')
        .send({username: 'admin'})
        .send({password: 'admin'})
        .send({remembercb: 'remember-me'})
        .redirects(0)
        .end(function (sreq, sres) {
            let cookie = sres.headers['set-cookie'];
            emitter.emit("setCookeie", cookie, isFlag);
        });
}

/**
 * 將設置的cookie與express共享
 * @param cookie
 */
function cookieReset(cookie, isFlag) {
    router.all('*', function (req, res, next) {
        res.header('set-cookie', cookie[0]);
        next();
    });
    if (isFlag) return;
    router
        .get('/', function (req, res) {
            res.sendFile('../static/index.html');
        })
        .get('/mit/*', function (req, res) {
            let proxy_url = proxyUri + (req.url).replace('mit', 'cmp');
            console.log('proxy:', proxy_url);
            //這里注意agent的緩存戳稽,它會緩存cookie,這樣導致某cookie失效后就無法使用了期升。
            //這里推薦你這樣做 superAgent.agent();
            agent
                .get(proxy_url)
                .end(function (areq, ares) {
                    if (ares.text) {
                    res.end(ares.text);
                    }else {
                        res.end('<h2>請求失敗</h2>');
                    }
                });
        })
        .all('/mitc/*', function (req, res) {
            if (req.url === '/mitc/login') {
                console.log('cookie超時惊奇,請求登錄頁了');
                login(true);
                res.redirect('/');
            } else {
                proxy.web(req, res);
                return;
            }
        });
};

module.exports = router;

基本思想是:開始使用anget登錄到該網站,并將cookie保存并設置給express播赁。之后
使用http-proxy代理來自iframe內的所有請求(iframe內的css颂郎、js等)。這里頁面cookie會過期容为,
這里并不希望它調到登錄頁面乓序,所有攔截它的登錄請求,再次登錄坎背。

ok成功解決了問題替劈,一個好周末就來了。
出現(xiàn)了一個cookie緩存的bug得滤,如果你和我一樣的代碼陨献,那么必須注意agent的緩存cookie(原因未知),使用必須看一下懂更。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末眨业,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子膜蛔,更是在濱河造成了極大的恐慌坛猪,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皂股,死亡現(xiàn)場離奇詭異墅茉,居然都是意外死亡,警方通過查閱死者的電腦和手機呜呐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門就斤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蘑辑,你說我怎么就攤上這事洋机。” “怎么了洋魂?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵绷旗,是天一觀的道長喜鼓。 經常有香客問我,道長衔肢,這世上最難降的妖魔是什么庄岖? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮角骤,結果婚禮上隅忿,老公的妹妹穿的比我還像新娘。我一直安慰自己邦尊,他們只是感情好背桐,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蝉揍,像睡著了一般链峭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上又沾,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天熏版,我揣著相機與錄音,去河邊找鬼捍掺。 笑死,一個胖子當著我的面吹牛再膳,可吹牛的內容都是我干的挺勿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼喂柒,長吁一口氣:“原來是場噩夢啊……” “哼不瓶!你這毒婦竟也來了?” 一聲冷哼從身側響起灾杰,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蚊丐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后艳吠,有當地人在樹林里發(fā)現(xiàn)了一具尸體麦备,經...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年昭娩,在試婚紗的時候發(fā)現(xiàn)自己被綠了凛篙。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡栏渺,死狀恐怖呛梆,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情磕诊,我是刑警寧澤填物,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布纹腌,位于F島的核電站,受9級特大地震影響滞磺,放射性物質發(fā)生泄漏升薯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一雁刷、第九天 我趴在偏房一處隱蔽的房頂上張望覆劈。 院中可真熱鬧,春花似錦沛励、人聲如沸责语。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坤候。三九已至,卻和暖如春企蹭,著一層夾襖步出監(jiān)牢的瞬間白筹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工谅摄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徒河,地道東北人。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓送漠,卻偏偏與公主長得像顽照,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闽寡,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內容