nodejs使用jsdom加载页面后执行脚本

浏览器加载页面然后执行脚本,这里是因为存在浏览器环境,能够加载DOM JS这些才能够执行脚本。jsdom可以做浏览器环境的一个替代,使用nodejs jsdom加载DOM JS后,再执行脚本也是可以的,当然jsdom也是可以被检测的。


var express = require('express');
var router = express.Router();

const jsdom = require('jsdom');
const {JSDOM} = jsdom;

const { Script } = require("vm");

var http = require('http');
var url = require('url'); 


var mysleep = function(time) {
  dellsfl = false;
  var startTime = new Date().getTime() + parseInt(time, 10);
  while(new Date().getTime() < startTime) {
    
  }
  
  dellsfl = true;
};


var mmm = 10;
  //jsdom配置
  var options =  {
    url: "https://xxx.xxx.chinatax.gov.cn:8443/",
    referrer: "https://dppt.xxx.chinatax.gov.cn:8443/",
    contentType: "text/html",
    userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
    includeNodeLocations: false, //保留由HTML解析器生成的位置信息,允许您使用nodeLocation()方法(如下所述)检索它。
    runScripts: "dangerously",//在页面内启用脚本
    beforeParse(window) {//在解析任何HTML并使用节点填充文档之前 这里可以改一些环境参数
       window.document.childNodes.length === 0;
       window.someCoolAPI = () => { /* ... */ };
       window.alert = function alert(){};
       window.navigation = {};
       window.document.cookie = '';

       window.innerWidth = 1920;

       window['UAParser'] = function(){};
       var UAParser = function(){};

      var XMLHttpRequest = window.XMLHttpRequest;
      XMLHttpRequest.prototype.open = function(){
          //debugger;
      };
      
      XMLHttpRequest.prototype.send = function(){
          //debugger;
      };
      
      XMLHttpRequest.prototype.setRequestHeader = function(a,b){
          //debugger;
      };

      window.XMLHttpRequest = XMLHttpRequest;

      var navigator = window.navigator;

    
      window.navigator = navigator;  
      var document = window.document;
      var location = window.location;

      document.createElement = function createElement(tagName){
       var tagname = tagName.toLowerCase() + "";

       
       if(tagname === 'canvas'){
           return {
               'getContext':function(b){
                 if(b === '2d'){
                     return {
                       'rect':function(a,b,c,d){
       
                       },
                       'isPointInPath':function(a,b,c){
                           if(a == b){
                              return false;
                           }
                           return true;
                       },
                       'textBaseline':'alphabetic',
                       'fillStyle':'#000000',
                       'fillRect':function(a,b,c,d){
       
                       },
                       'font':'10px sans-serif',
                       'fillText':function(a,b,c){
       
                       },
                       'globalCompositeOperation':'source-over',
                       'beginPath':function(){
       
                       },
                       'arc':function(a,b,c,d,e,f){
       
                       },
                       'closePath':function(){
       
                       },
                       'fill':function(a){
       
                       },
       
                     };
                 }

                 if(b === 'webgl'){
                     return {
                           'getParameter':function(m){
                                 if(m == 37445){
                                    return 'Google Inc. (NVIDIA)';
                                 }
                                 if(m == 37446){
                                   return 'ANGLE (NVIDIA, NVIDIA GeForce RTX 2060 Direct3D11 vs_5_0 ps_5_0, D3D11)';
                                }
                           },
                           'getExtension':function(g){
                                if(g === 'WEBGL_debug_renderer_info'){
                                      return {
                                       'UNMASKED_VENDOR_WEBGL':37445,
                                       'UNMASKED_RENDERER_WEBGL':37446
                                      };
                                }
                           },
                           'getSupportedExtensions':function(){
                               
                               return ["ANGLE_instanced_arrays","EXT_blend_minmax","EXT_color_buffer_half_float","EXT_disjoint_timer_query","EXT_float_blend","EXT_frag_depth","EXT_shader_texture_lod","EXT_texture_compression_bptc","EXT_texture_compression_rgtc","EXT_texture_filter_anisotropic","EXT_sRGB","KHR_parallel_shader_compile","OES_element_index_uint","OES_fbo_render_mipmap","OES_standard_derivatives","OES_texture_float","OES_texture_float_linear","OES_texture_half_float","OES_texture_half_float_linear","OES_vertex_array_object","WEBGL_color_buffer_float","WEBGL_compressed_texture_s3tc","WEBGL_compressed_texture_s3tc_srgb","WEBGL_debug_renderer_info","WEBGL_debug_shaders","WEBGL_depth_texture","WEBGL_draw_buffers","WEBGL_lose_context","WEBGL_multi_draw"];

                           }
                     };
                 }

                 if(b === 'experimental-webgl'){
                   return {

                   };
                 }
               },
               'style':{
                   'display':''
               },
               'toDataURL':function(){//canvas的指纹,暂时写死 test
                   return 'data:image/png;base64,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';
               }
             };
       }

     }
     
    },
    cookieJar: new jsdom.CookieJar()
 };

//中文文档 https://segmentfault.com/a/1190000014844043
//cnpm install canvas --save 安装包 否则报错


router.post('/getSt', function(request, response, next) {

   var html = request.body.html;

   //解码
   var b = new Buffer(html, 'base64');
   html = b.toString();

   //html = decodeURI(html);
   var result = {};
   result.code = '0';
   result.message = '处理成功';

   if(html === '' || html == null || html == undefined){
      result.code = '-1';
      result.message = '参数html为空';
      response.writeHead(200, {'Content-Type': 'application/json'});
      response.end(JSON.stringify(result));
      return;
   }

   try {

        //获取函数  ]();}}i(
        var index1 = html.indexOf('}}}i(')+'}}}i('.length;
        var index2 = html.indexOf('!function(b,a)');
        var functionName = html.substring(index1,index2-2);
        
        html = html.substring(html.indexOf('/body'));
        var myscript = html.substring(html.indexOf('<script>')+'<script>'.length,html.indexOf('</script>'));
          
         
         let dom = new JSDOM(
           `<html><body></body></html>`,
           // html,
            options
          );
           //console.log(dom.window.document.cookie); 

          // const dom = new JSDOM(``, { runScripts: "outside-only" });
           
           var eval = dom.window.eval;

	        // 匿名的立即执行函数,因访问了全局变量a,所以也是一个闭包
          !(function test (ee){
              
              //mmm = 100;
              ee(myscript);//这里多次执行导致内存未释放

             var st = ee('window.'+functionName);
          
              result.data = st;
              console.log('st res',st);
          })(eval);

      
           dom.window.location.href = 'https://dppt.xxx.chinatax.gov.cn:8443/';
           mysleep(200);
           dom.window.close();

           dom = null;
           console.log('dom',dom);
           response.writeHead(200, {'Content-Type': 'application/json'});
           response.end(JSON.stringify(result));
   } catch (error) {
      console.log(error);
      var result = {};
      result.code = '-1';
      result.message = error.message != undefined?error.message:error.data;
      response.writeHead(200, {'Content-Type': 'application/json'});
      response.end(JSON.stringify(result));
   }finally{
       // dom = new JSDOM;
        dom = null;

       // dom = new JSDOM(
       // `<html><body></body></html>`,
       //   options
       // );
   }

});


module.exports = router;

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
回答: 要在Node.js中安装jsdom模块,你可以使用npm来安装。首先,确保你已经安装了Node.js和npm。然后,在命令行中运行以下命令来安装jsdom模块: ``` npm install jsdom ``` 这将会在你的项目中安装jsdom模块。安装完成后,你可以在你的代码中引入jsdom模块,并使用它来模拟DOM环境。你可以使用`JSDOM`类来创建一个DOM实例,传入一个包含HTML代码的字符串作为参数。例如,你可以这样创建一个包含一个`<p>`元素的DOM实例: ```javascript const { JSDOM } = require('jsdom'); const html = '<p>Hello world</p>'; const dom = new JSDOM(html); console.log(dom.window.document.querySelector('p').textContent); ``` 这将会输出 "Hello world"。希望这能帮到你!\[1\]\[2\] #### 引用[.reference_title] - *1* *2* [使用 jsdom 模块在 Node.js 中模拟 DOM 环境](https://blog.csdn.net/gaoxiangfei/article/details/130902473)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [nodejsjsdom安装](https://blog.csdn.net/xiaocie3456/article/details/18351011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liberty888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值