精华内容
下载资源
问答
  • 这就是 V8 中执行一段JS代码的整个过程,梳理一下: 首先通过词法分析和语法分析生成 AST 将 AST 转换为字节码 由解释器逐行执行字节码,遇到热点代码启动编译器进行编译,生成对应的机器码, 以优化执行效率 关于这...

    前端相对来说是一个比较新兴的领域,因此各种前端框架和工具层出不穷,让人眼花缭乱,尤其是各大厂商推出小程序之后各自制定标准,让前端开发的工作更加繁琐,在此背景下为了抹平平台之间的差异,诞生的各种编译工具/框架也数不胜数。但无论如何,想要赶上这些框架和工具的更新速度是非常难的,即使赶上了也很难产生自己的技术积淀,一个更好的方式便是学习那些本质的知识,抓住上层应用中不变的底层机制,这样我们便能轻松理解上层的框架而不仅仅是被动地使用,甚至能够在适当的场景下自己造出轮子,以满足开发效率的需求。

    站在 V8 的角度,理解其中的执行机制,也能够帮助我们理解很多的上层应用,包括Babel、Eslint、前端框架的底层机制。那么,一段 JavaScript 代码放在 V8 当中究竟是如何执行的呢?

    首先需要明白的是,机器是读不懂 JS 代码,机器只能理解特定的机器码,那如果要让 JS 的逻辑在机器上运行起来,就必须将 JS 的代码翻译成机器码,然后让机器识别。JS属于解释型语言,对于解释型的语言说,解释器会对源代码做如下分析:

    • 通过词法分析和语法分析生成 AST(抽象语法树)
    • 生成字节码

    然后解释器根据字节码来执行程序。但 JS 整个执行的过程其实会比这个更加复杂,接下来就来一一地拆解。

    1.生成 AST

    生成 AST 分为两步——词法分析和语法分析。

    词法分析即分词,它的工作就是将一行行的代码分解成一个个token。比如下面一行代码:

    let name = 'sanyuan'

    其中会把句子分解成四个部分:

    918f3be8b4b91bf12b708b7ffef3fcbe.png

    即解析成了四个token,这就是词法分析的作用。

    接下来语法分析阶段,将生成的这些 token 数据,根据一定的语法规则转化为AST。举个例子:

    let name = 'sanyuan'console.log(name)

    最后生成的 AST 是这样的:

    2ba6a3bad2bb7fc7d060394d33814710.png

    当生成了 AST 之后,编译器/解释器后续的工作都要依靠 AST 而不是源代码。顺便补充一句,babel 的工作原理就是将 ES6 的代码解析生成ES6的AST,然后将 ES6 的 AST 转换为 ES5 的AST,最后才将 ES5 的 AST 转化为具体的 ES5 代码。由于本文着重阐述原理,关于 babel 编译的细节就不展开了,推荐大家去读一读荒山的babel文章, 帮你打开新世界的大门: )

    回到 V8 本身,生成 AST 后,接下来会生成执行上下文,关于执行上下文,可以参考上上篇《JavaScript内存机制之问——数据是如何存储的?》中对于上下文压栈出栈过程的讲解。

    2. 生成字节码

    开头就已经提到过了,生成 AST 之后,直接通过 V8 的解释器(也叫Ignition)来生成字节码。但是字节码并不能让机器直接运行,那你可能就会说了,不能执行还转成字节码干嘛,直接把 AST 转换成机器码不就得了,让机器直接执行。确实,在 V8 的早期是这么做的,但后来因为机器码的体积太大,引发了严重的内存占用问题。

    给一张对比图让大家直观地感受以下三者代码量的差异:

    8bdcb90a1a7695ed24aa96d548d834aa.png

    很容易得出,字节码是比机器码轻量得多的代码。那 V8 为什么要使用字节码,字节码到底是个什么东西?

    子节码是介于AST 和 机器码之间的一种代码,但是与特定类型的机器码无关,字节码需要通过解释器将其转换为机器码然后执行。

    字节码仍然需要转换为机器码,但和原来不同的是,现在不用一次性将全部的字节码都转换成机器码,而是通过解释器来逐行执行字节码,省去了生成二进制文件的操作,这样就大大降低了内存的压力。

    3. 执行代码

    接下来,就进入到字节码解释执行的阶段啦!

    在执行字节码的过程中,如果发现某一部分代码重复出现,那么 V8 将它记做热点代码(HotSpot),然后将这么代码编译成机器码保存起来,这个用来编译的工具就是V8的编译器(也叫做TurboFan) , 因此在这样的机制下,代码执行的时间越久,那么执行效率会越来越高,因为有越来越多的字节码被标记为热点代码,遇到它们时直接执行相应的机器码,不用再次将转换为机器码。

    其实当你听到有人说 JS 就是一门解释器语言的时候,其实这个说法是有问题的。因为字节码不仅配合了解释器,而且还和编译器打交道,所以 JS 并不是完全的解释型语言。而编译器和解释器的 根本区别在于前者会编译生成二进制文件但后者不会。

    并且,这种字节码跟编译器和解释器结合的技术,我们称之为即时编译, 也就是我们经常听到的JIT

    这就是 V8 中执行一段JS代码的整个过程,梳理一下:

    1. 首先通过词法分析和语法分析生成 AST
    2. 将 AST 转换为字节码
    3. 由解释器逐行执行字节码,遇到热点代码启动编译器进行编译,生成对应的机器码, 以优化执行效率

    关于这个问题的拆解就到这里,希望对你有所启发。

    展开全文
  • 前言各位小伙伴,大家好,这次咱们来说一下关于爬虫方向的一个知识,Python如何执行js,快来看看吧!!!为什么要引出Python执行js这个问题?都说术业有专攻,每个语言也都有自己的长处和短处。在爬虫方向,Python绝对是...

    eeeb0936f10982bacfcf9fbdd54029bd.png

    前言
    各位小伙伴,大家好,这次咱们来说一下关于爬虫方向的一个知识,Python如何执行js,快来看看吧!!!

    bb3ae010718bb11551708012c0e044a3.png

    为什么要引出Python执行js这个问题?
    都说术业有专攻,每个语言也都有自己的长处和短处。在爬虫方向,Python绝对是扛把子,近几年随着AI的火爆,需要各种各样的数据,所以,爬虫需求也跟着水涨船高起来。
    我们做爬虫的当然是爬的爽,但是估计人家后台在骂街,毕竟谁都不希望自己的数据被弄走,所以后台反爬技术也在快速提升,一攻一防就这么在拉锯着。
    现在为了防止反爬,前端使用的反爬技术比较多的是js代码混淆。什么是js代码混淆?正常代码
    我们现在看一段js代码,代码逻辑很简单,就是拼接时间返回。
    function formatDate(now) { var now = new Date(1230999938); var year=now.getFullYear(); var month=now.getMonth()+1; var date=now.getDate(); var hour=now.getHours(); var minute=now.getMinutes(); var second=now.getSeconds(); return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; } 混淆代码
    我随便找了个在线的js代码混淆网站。js代码
    function formatDate(mz1){var KkkGDiH2=new window["x44x61x74x65"](1230999938);var tsk3=KkkGDiH2['x67x65x74x46x75x6cx6cx59x65x61x72']();var YMreyP4=KkkGDiH2['x67x65x74x4dx6fx6ex74x68']()+1;var Ozo5=KkkGDiH2['x67x65x74x44x61x74x65']();var QMYEc$eD6=KkkGDiH2['x67x65x74x48x6fx75x72x73']();var JfXVV_Akq7=KkkGDiH2['x67x65x74x4dx69x6ex75x74x65x73']();var $mP8=KkkGDiH2['x67x65x74x53x65x63x6fx6ex64x73']();return tsk3+"x2d"+YMreyP4+"x2d"+Ozo5+" "+QMYEc$eD6+"x3a"+JfXVV_Akq7+"x3a"+$mP8
    上面这个真的不是我瞎写的,混淆之后就是这样子的,不信看图片。

    a62d5a2883f39919bb2614042722ec78.png


    可能我们会有个疑问,js代码都成这玩意了,还能执行吗? 答案是肯定的。即使js代码非常乱,但还是可以执行的,结果跟上面的是一样的。
    这就造成了一个问题,我们在做爬虫时,如果需要,多多少少可能都要研究一下js代码,然后进行js解密一下,但是,但是,要是代码都混淆成了这了,还怎么解?
    一点逻辑都看不通了,基本上不可用Python按照js逻辑重写出来了...
    很巧,小编也是卡在这里...后来我就想,要是Python能执行js代码就好了,不用管函数里面的逻辑了,只拿函数返回值就好了。Python第三方包Execjs
    可能是吧,不止我一个人遇到了这种情况,所以大佬们就开发出来这种工具包,用于执行js代码。安装
    在安装之前,需要有node环境,这里就不举栗子了,下一步下一步就好了。
    pip3 install PyExecJS
    Execjs用法超级简单的,几行代码。执行js
    注:由于上述js代码会生成window对象,并不能直接执行成功,需要额外的其他辅助,这里简单的举一下其他例子。正常js代码
    function add(x, y) { return x + y; } Python执行js代码
    import execjs ctx = execjs.compile(""" function add(x, y) { return x + y; } """) print(ctx.call("add", 1, 2))
    执行结果如下图所示:

    7407642a343c393b054e0468c3741ec7.png

    混淆js代码
    function add(bi1,Pl$2){return bi1+Pl$2}
    Python执行混淆js代码
    import execjs ctx = execjs.compile(""" function add(bi1,Pl$2){return bi1+Pl$2} """) print(ctx.call("add", 1, 2))
    执行结果如下图所示:

    8ece558bd9e350421335b873677d372a.png


    可以看到,即使再混淆,只要执行的是js代码,都是没啥问题的。
    上述拼接时间返回的js混淆代码也是可以执行的,但是它多了一个window对象,需要node安装jsdom才行,由于网络设置有问题,实在是下载不了举例子,实在是抱歉。
    或者使用selenium打开游览器执行再返回也行,当然,速度更慢。结尾
    反爬和爬虫一直都是一攻一防,以后可能这种情况会更严重,但是在Python庞大的生态中总能找到不错的方案。人生苦短,Python当歌。

    展开全文
  • 问题是这个函数非常复杂,不容易将其换成Java代码重写,故需要安卓直接执行js代码获得那个值。 我在网上找了一段时间希望找到能直接运行js的Java类库,虽然找到了rhino,但是还是没有解决问题。所以我还是换一种思路...

    最近有一个需求,就是要在安卓端获取某个值,这个值是由js文件里的某个函数生成的。问题是这个函数非常复杂,不容易将其换成Java代码重写,故需要安卓直接执行js代码获得那个值。

    我在网上找了一段时间希望找到能直接运行js的Java类库,虽然找到了rhino,但是还是没有解决问题。所以我还是换一种思路吧,直接用WebView这个强大的东西

    一、准备工作

    准备一个html文档,里面嵌入需要运行js代码,然后把它复制到assets目录下。Android Studio没有这个目录,自己在main文件夹里新建一个assets文件夹就行。这里我简单写一个html文件

    test.html

    <!DOCTYPE html>
    <html>
    <head>
    	<title>test</title>
    	<script type="text/javascript">
    		function add(){
    			return 5+5;
    		}
    	</script>
    </head>
    <body>
    	<div>This is a test</div>
    </body>
    </html>
    

    二、项目布局

    因为我们的重点是执行js文件,所以WebView界面如何不是重点,我这里就直接设为不可见

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按钮"/>
        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:visibility="gone"
            android:layout_height="500dp"/>
    
    </LinearLayout>
    

    三、Java代码

    大概代码如下,也就是找到布局里的button和webview,然后初始化webview

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
        private Button btn;
        private WebView webView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            webView = findViewById(R.id.webView);
            btn = findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    openWebView();
                }
            });
        }
    
        private void openWebView(){
            webView.setWebViewClient(new WebViewClient(){
    
                //一定要等页面加载完再调用evaluateJavascript(),否则.....入坑吧
                @Override
                public void onPageFinished(WebView view, String url) {
                    super.onPageFinished(view, url);
                    //执行完add()函数之后执行Callback回调函数,s的值就是执行完add()之后得到的值
                    webView.evaluateJavascript("javascript:add()", new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String s) {
                            Log.e("11111111", "onReceiveValue: "+ s );
                        }
                    });
                }
            });
            WebSettings webSettings = webView.getSettings();
            webSettings.setDefaultTextEncodingName("UTF-8");
            //webSettings.setBuiltInZoomControls(true);
            //webSettings.setUseWideViewPort(true);
            webSettings.setJavaScriptEnabled(true);//这个是重点,不设置则不能执行js代码
            //webSettings.setDomStorageEnabled(true);
            //webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    
            webView.loadUrl("file:///android_asset/test.html");
    
        }
    
    }
    

    上面的代码非常简单,其实就是重写onPageFinished()方法(加载完网页之后会执行),然后再调用webView.evaluateJavascript()方法就可以了
    得到执行完js后的值

    展开全文
  • android执行js回调函数

    千次阅读 2019-01-18 16:53:09
    上干货! 应用场景:由网页端触发按钮,通知原生去请求...这里省略了安卓接收js参数的步骤,将成功的回调函数赋值给字符串mSuccess,如下图result为请求后台接口返回的结果,安卓执行js的回调函数正如下图代码 ...

    上干货!

    应用场景:由网页端触发按钮,通知原生去请求服务器,请求完成后,执行网页js的回调函数

    js端代码:

    android代码:

    这里省略了安卓接收js参数的步骤,将成功的回调函数赋值给字符串mSuccess,如下图result为请求后台接口返回的结果,安卓执行js的回调函数正如下图代码

    展开全文
  • Frida Java Hook 详解(安卓9):代码及示例(上)前言1.1 FRIDA SCRIPT的"hello world"1.1.1 "hello world"脚本代码示例1.1.2 "hello world"脚本代码示例详解1.2 Java层拦截普通方法1.2.1 拦截普通方法脚本示例1.2.2 ...
  • js安卓互相调用

    2016-11-30 11:50:17
    今天写的是安卓中调用html中的js,如果安卓中和js想要相互调用,首先要代码设置webview能够执行javaScript 默认是不执行代码如下图 然后像webview注册一个对象onfire ,同样也传递一个JavaScriptCallBack实例给...
  • JS方法书写时,如果一个大方法体中还要调用其他小方法时,要注意回调问题,由于在js代码是顺序执行的,不是按照方法一步步一层层执行的 这个问题在苹果手机中可以复现,安卓中没问题
  • 安卓原生app调用js方法,js方法应写在html下的script标签内,不能有任何function包裹,例如angular的controller层,这样APP也是获取不到的; 所以只有放在html中单独加个script标签; 如果需要APP返回值再调用...
  • 0×00 背景 在android的sdk中封装了webView控件。这个控件主要用开控制的网页浏览。在程序中装载webView控件,可以设置属性...能实现本地java和js的交互。利用addJavascriptInterface这个接口函数可实现穿透webk
  • Promise是JavaScript异步编程中的重要概念,也...和Java不同的是,JS中的单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,即就是一次只能完成一项任务,这个任务执行完后才能执行下一个,这期间它...
  • 1,在交互规则里,js调用安卓,统一传一个action,作为标记,表明要执行的行动中的特定方法,然后传入参数,json格式的参数, 最后一个是回调方法。可以匿名实现回调方法。非常的方便。js调用安卓只需要一个方法,就...
  • mui框架使用video.js来播放视频,苹果手机全屏没问题,...js冲突了,touch事件执行了两遍,解决办法是video.js的全屏按钮点击一次后就阻止,代码 mui("#my-video").on("touchstart",".vjs-control",function(){ ...
  • 最近做了一个H5,说要提供一个底部,可以...代码如下: window.onload = function () { var u = navigator.userAgent; if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {//安卓手机 //执行...
  • 在最近的工作中经常遇到需要通过js来判断访问的浏览器亦或者终端执行指定代码,个人通过网络上查询到一些不错的判断方法进行整理和个人总结的分享: 通过JS判断各种访问终端的index of方法 //判断访问终端 var ...
  • 前言 更多的IPC细节请看这里 App之间的五种通信方式,它分别有URL Scheme,Keychain,UIPastedboard,...ios 有类似安卓的aidl? Is there equivalent of AIDL on other platforms (iOS, Blackberry
  • 1.先写好toast的js代码: /**  * 模仿android里面的Toast效果,主要是用于在不打断程序正常执行的情况下显示提示数据  * @param config  * @return  */ var Toast = function(config){  this....
  • 在webview中可以使用code_mirror可以做成一...js代码如下,会自动生成一个html网页代码,自动插入到body中。 window.onload = function () { var name = SourceEditor.getName(); var extension = getExtensi...
  • appium测试安卓app记录

    2020-07-31 16:30:12
    一、基本概述 appium的核心是暴露的一系列REST API的server。 server监听一个端口,接收...client即发送command的设备,即client是发送代码的客户端,代码可以是java/ruby/js,只要实现了webdriver标准协议就可。 1.1 s
  • 安卓WebView改变网页文字背景颜色

    千次阅读 2018-09-27 15:15:51
    原理为动态向html里面注入js方法,然后执行,不难,直接贴代码 关键代码 在onPageFinished方法里面输入webview.loadUrl(“javascript:”+“js方法名或者.js”)。 mWebview.setWebViewClient(new WebViewClient() { ...
  • 问题:浏览器js执行window.location.reload(),正常情况下reload()后页面依然会向后台发出请求,但在安卓版本的微信浏览器中reoad()后并没有真正的向后台发送请求。因为微信默认做为缓存来处理了。 解决方案 请求...
  • JS中的this问题

    2019-05-17 05:25:29
    最近在使用react native开发安卓app的过程中,总是遇到this指针所在上下文切换,导致从this中调用对象或者方法时,总是报xxx is undefine, 这是因为JS中的this十分灵活,随着代码执行上下文的不同,this指针所指的...
  • ReactNative下安卓原生模块的日志输出

    千次阅读 2018-05-29 11:04:14
    包括其他的第三方开源组件一样可以用,JS端的代码只需要在程序的启动时注册一次事件监听接口,而无需在每个组件里注册。 1. JS端建立事件监听接口 为防止重复创建,可以在添加前先执行移除操作。 参数1是...
  • Auto.js是利用安卓系统的“辅助功能”实现类似于按键精灵一样,可以通过代码模拟一系列界面动作的辅助工作。 因为是开源框架所以安全性很高,他能在手机上模拟人的重复繁琐的工作,不打破被执行的APP规则,不修改,...
  • 项目中需要安卓原生和js进行相互通信,使用的是github上星级比较高的jsBridge;按照它的文档写到项目中,但是注册js的方法一直不执行 然后就去github上,看有人遇到过这个问题没!偶然发现一条网友提出的,给了...
  • Auto.js是利用安卓系统的“辅助功能”实现类似于按键精灵一样,可以通过代码模拟一系列界面动作的辅助工作。 因为是开源框架所以安全性很高,他能在手机上模拟人的重复繁琐的工作,不打破被执行的APP规则,不修改,...
  • 话不多说,上代码: html: <input id="copyObj" value="哈哈哈" /> js: copyTxt(text) { // 数字没有 .length 不能执行selectText 需要转化成字符串 const textString = text.toString(); let ...
  • 微信公众号 https://mp.weixin.qq.com/s/E51lKQOojsvhHvACIyXwhw作者:黄文佳常见错误的分类对于用户在访问页面时发生的错误,主要包括以下几个类型:1、js运行时错误JavaScript代码在用户浏览器中执行时,由于一些...
  • Android app 与网页交互 WebView 与JS(JavaScript)交互 安卓webview 传递数据到网页本文包含如下要点:WebView的基础用法; 执行JavaScriptInterface及其方式; demo app的AndroidStudio源代码。老大说做个demo把...
  • 在各类平台上的各种浏览器和移动设备兼容的时候,...那就可以确定要做的第一步就是写一个 页面加载就执行JS 函数。函数的作用就是帮我们拿到浏览器的信息。 window.onload = function() { //这里面写你要干的
  • 形如$(document).ready(function(){ js代码 }) 在苹果手机中不执行js代码,在安卓手机中可以 但是换成 window.onload = function(){ js代码 } 却都可以执行。这是为什么呢?

空空如也

空空如也

1 2 3 4
收藏数 68
精华内容 27
关键字:

安卓执行js代码