nodejs jsdom TypeError:Object [object global]没有方法'postMessage'

时间:2014-10-22 09:15:50

标签: javascript node.js jsdom

这是我的Nodejs Express应用程序页面中的路由器/ index.js页面 我试图解析一些网站 - 这里有两段代码作为例子。 获取页面后,我使用jsdom模块处理数据。但是有一个问题 - 本例中的othersite.com工作正常,而site.com在解析和呈现页面后崩溃(就像在我看来一样)并出现错误:

http://s7.addthis.com/static/r07/core159.js:4
){!_ate.bro.ie6&&!_ate.bro.ie7&&W&&W.contentWindow&&W.contentWindow.postMessag
                                                                    ^
TypeError: Object [object global] has no method 'postMessage'
    at Object.r [as msg] (http://s7.addthis.com/static/r07/core159.js:4:6291)
    at Object.window._ate.m.initPostMessage (http://s7.addthis.com/static/r07/core159.js:7:11410)
    at null._onTimeout (http://s7.addthis.com/static/r07/core159.js:7:7874)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

还有其他条件块会产生相同的错误,但那里没有那么多代码 谁能告诉我这是什么问题?

router.get('/', function(req, res) {
var url_parts = url.parse(req.url, true),
    query = url_parts.query,
    video_url,
    file_url,
    videoTitle,
    embedCode,
    remoteAddr = req.connection.remoteAddress,
    base64_encode = require('base64').encode;
if (query.link) {
        var pathObj = url.parse(query.link, true);
        var options = {
            host: pathObj.host,
            port: 80,
            path: pathObj.path,
            headers: {
                "X-forwarder-for" : "90.90.90.90" // just sample ip
            }
        };
        http.get(options, function(response){

            var allChunk = '';
            response.on('data', function(chunk) {
                    allChunk += chunk;
            });
            response.on('end', function(){
                var doc = jsdom.jsdom(allChunk);
                var serializedChunk = doc.documentElement.outerHTML;
                jsdom.env(
                    serializedChunk,
                    ["http://code.jquery.com/jquery.js"],
                    function (errors, window) {
                        remoteAddr = remoteAddr;
                        videoTitle = window.$('title').text();
                        var rawHtml = window.$('body').html();
                        var handler = new htmlparser.DefaultHandler(function (error, dom) {});
                        var parser = new htmlparser.Parser(handler);
                        parser.parseComplete(rawHtml);
                        var objectDom = handler.dom;
                        if (query.link.indexOf('site.com') != -1) {
                            var blockHTML = window.$('#player embed').attr('flashvars');
                            var flash_vars_url = url.parse('/?' + blockHTML, true);
                            var queryFlashVars = flash_vars_url.query;
                            file_url = queryFlashVars.flv_url;
                            embedCode = window.$('input[name="media_embed_code"]').val();
                            res.render('link', { title: 'source link', link: file_url, videoTitle: videoTitle, embedCode: embedCode, sourceLink: query.link });
                        } else if (query.link.indexOf('othersite.com') != -1) {
                            file_url = window.$('.downloadList li a').attr('href');
                            var embedObject = /\$\('#clip_text'\).val\(*"([^"]*)/g.exec(rawHtml);
                            embedCode = embedObject[1];
                            res.render('link', { title: 'source link', link: file_url, videoTitle: videoTitle, embedCode: embedCode, sourceLink: query.link });

                        } else {
                            res.status(404);
                            res.render('error', {
                                message: 'Not found',
                                error: {}
                            });
                        }

                    }
                );

            });
        }).on("error", function(e){
            console.log("Got error: " + e.message);
        }).end();
} else {
    res.render('index', { title: 'title' });
}

});

我将不胜感激任何帮助。

2 个答案:

答案 0 :(得分:0)

您可以从错误说明中看到:

你试图打电话给ate.bro.ie6&&!_ ate.bro.ie7&& W&& W.contentWindow&& W.contentWindow.postMessage

但是内容窗口没有这样的方法。您加载某些内容并覆盖该模块的可能原因。

在提供的源代码中(以及http://s7.addthis.com/static/r07/core159.js的去混淆)我看到它在服务器端的某个库似乎模拟了“浏览器”窗口对象行为......但是你破坏了windows上下文所以它无法工作

我认为here类似的问题

答案 1 :(得分:0)

在我看来,有些代码试图执行window.postMessage,并且这种方法在jsdom中不存在。此代码测试是否可以调用window.postMessage

var jsdom = require("jsdom");

var document = jsdom.env({
    html: "<html><head><script>window.postMessage();</script></head><body></body></html>",
    features: {
        FetchExternalResources: ["script"],
        ProcessExternalResources: ["script"]
    },
    done: function (errors, w) {
        console.log(errors);
    }
});

生成此输出:

[ { type: 'error',
    message: 'Running file:///tmp/t2/test.js:undefined:undefined<script> failed.',
    data:
     { error: [TypeError: Object [object global] has no method 'postMessage'],
       filename: 'file:///tmp/t2/test.js:undefined:undefined<script>' } } ]

我还检查了代码:

$ npm install jsdom
$ cd node_modules/jsdom
$ grep postMessage `find . -type f`
[no results]