导航:首页 > 编程语言 > androidjsprompt

androidjsprompt

发布时间:2024-06-23 06:22:02

『壹』 h5页面和app页面怎么通讯

通讯方法如下:
URL Scheme 是最常见的方法了,它的核心概念是拦截URL。
APP实现了一个webview,H5在其内打开。
它可以拦截到H5发生的跳转信息,如URL。如果以URL作为通信依据,就可以随意约定个URL,如:建立通信:https://__bridge_loaded__ 获取token:https://nativaAPI_getToken
H5就可以通过跳转到该地址被APP拦截,APP识别到了约定的URL触发对应方法。
2. 拦截打印日志
APP的webview有对应的监听,可以拦截到js的 alert 等。就可通过输出 alert("标识", "方法名", "参数") 等方法进行通信。IOS 由于安全限制,UIWebView 性能原因已弃用不考虑,WKWebView 对 alert 等方法做了拦截,需要做代理处理一下即可。Android 通过 WebView.addjavascriptInterface 方法实现。但因 Android 4.2 以前的系统中没有正确限制使用WebView.addJavascriptInterface,导致攻击者可以伪造JS桥接调用原生方法,存在安全漏洞,因此较少见。Google在Android 4.2 版本中修复了他,通过在Java方法内的最上面声明一句@JavascriptInterface,从而避免漏洞攻击。若想 4.2 版本前使用就要另寻出路,window.prompt 一问一答的机制恰好可以满足,Android onJsPrompt方法中去解析传递过来的文本,将处理结果返回给JS。
3. window注入
window注入就比较好理解了,就是双方在JS的window下写入通信变量。其实上面两种方法也多少会涉及window注入。它是一个对象,常用的有这几个方法(想用什么自己写入)。

『贰』 如何设置WebView支持js的Alert,Confirm,Prompt函数的弹出提示框

默认情况下,Android WebView是不支持js的Alert(),Confirm(),Prompt()函数的弹出提示框的.即使设置了setJavaScriptEnabled(true);也是没用的.那么,如何才能让WebView可以支持js的这3个函数呢.可以通过设置WebChromeClient对象来完成.WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等等.
这里主要重写WebChromeClient的3个方法:
onJsAlert :警告框(WebView上alert无效,需要定制WebChromeClient处理弹出)
onJsPrompt : 提示框.
onJsConfirm : 确定框.
效果图分别为:
1.Alert
2.Prompt
3.Confirm
先来看看js的页面代码:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<script type="text/javascript">
function call(){
var value = document.getElementById("input").value;
alert(value);
}
//警告
function onAlert(){
alert("This is a alert sample from html");
}
//确定
function onConfirm(){
var b = confirm("are you sure to login?");
alert("your choice is "+b);
}
//提示
function onPrompt(){
var b = prompt("please input your password","aaa");
alert("your input is "+b);
}
</script>
</head>
<body>
<input type="text" id="input" value="default"/>
<button onclick=call()>点我弹出Alert</button></br>
<input type="button" value="alert" onclick="onAlert()"/></br>
<input type="button" value="confirm" onclick="onConfirm()"/></br>
<input type="button" value="prompt" onclick="onPrompt()"/></br>
</body>
</html>
Android代码:
package com.example.chenys.webviewdemo;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.TextView;
/**
* Created by mChenys on 2015/11/19.
*/
public class TestAlertActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
setContentView(webView);
webView.requestFocus();
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);//启用支持js
//设置响应js 的Alert()函数
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder b = new AlertDialog.Builder(TestAlertActivity.this);
b.setTitle("Alert");
b.setMessage(message);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
b.setCancelable(false);
b.create().show();
return true;
}
//设置响应js 的Confirm()函数
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder b = new AlertDialog.Builder(TestAlertActivity.this);
b.setTitle("Confirm");
b.setMessage(message);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
b.create().show();
return true;
}
//设置响应js 的Prompt()函数
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
final View v = View.inflate(TestAlertActivity.this, R.layout.prompt_dialog, null);
((TextView) v.findViewById(R.id.prompt_message_text)).setText(message);
((EditText) v.findViewById(R.id.prompt_input_field)).setText(defaultValue);
AlertDialog.Builder b = new AlertDialog.Builder(TestAlertActivity.this);
b.setTitle("Prompt");
b.setView(v);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String value = ((EditText) v.findViewById(R.id.prompt_input_field)).getText().toString();
result.confirm(value);
}
});
b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
b.create().show();
return true;
}
});
webView.loadUrl("file:///android_asset/index3.html");
}
}
有2个需要注意的:
1.重写onJsPrompt 方法,需要我们自定一个提示的布局文件,如下:prompt_dialog.xml
就是一个提示的TextView和输入文本的EditTex而已.
[html] view plain
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/prompt_message_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/prompt_input_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="250dp"
android:selectAllOnFocus="true"
android:scrollHorizontally="true"/>
</LinearLayout>
2.WebView需要支持js的话,要记得加启用js的支持.
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);

『叁』 onjsprompt 浣曟椂璋冪敤

寮虹殑椤甸潰鎴戜滑浼氬亸鍚戜簬浣跨敤native鏉ュ畬鎴愶紝鑰屼竴鏃︿娇鐢ㄤ簡h5锛屼负浜嗗湪h5涓灏藉彲鑳界殑寰楀埌native鐨勪綋楠岋紝鎴戜滑native灞傞渶瑕佹毚闇蹭竴浜涙柟娉曠粰js璋冪敤锛屾瘮濡傦紝寮筎oast鎻愰啋锛屽脊Dialog锛屽垎浜绛夌瓑锛屾湁鏃跺欑敋鑷虫妸h5鐨勭綉缁滆锋眰鏀剧潃native鍘诲畬鎴愶紝鑰孞SBridge鍋氬緱濂界殑涓涓鍏稿瀷灏辨槸寰淇★紝寰淇$粰寮鍙戣呮彁渚涗簡JSSDK锛岃SDK涓鏆撮湶浜嗗緢澶氬井淇native灞傜殑鏂规硶锛屾瘮濡傛敮浠橈紝瀹氫綅绛夈
閭d箞锛屾庝箞鍘诲疄鐜颁竴涓鍏煎笰ndroid鍚勭増鏈鍙堝叿鏈変竴瀹氬畨鍏ㄦх殑JSBridge鍛锛熸垜浠鐭ラ亾锛屽湪WebView涓锛屽傛灉java瑕佽皟鐢╦s鐨勬柟娉曪紝鏄闈炲父瀹规槗鍋氬埌鐨勶紝浣跨敤WebView.loadUrl(鈥渏avascript:fu

『肆』 webview判断 js是否有 交互对象

android与js交互有两种方式,第一种是通过系统提供的@JavascriptInterface注解实现,第二种就是js注入。下面来详细讲解一下二者的使用方式,原理,区别。
一、@JavascriptInterface实现
实现步骤:
a.设置WebView支持js脚本
b.为提供给js调用的方法加上@JavascriptInterface注解c.给WebView添加js接口
[java] view plain
webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new JSMethod(mContext), "lh");public class JSMethod {
private Context mContext;
public JSMethod(Context mContext) {
this.mContext = mContext;
}
@JavascriptInterface
public void toast(String msg) {
Toast.makeText(mContext, msg == null ? "" : msg, Toast.LENGTH_SHORT).show();}
}
js端调用android方法:
[javascript] view plain
lh.toast("Hello,China!");
android端执行js方法:
[java] view plain
webView.loadUrl("javascript:console(" + "'Hello,China!'" + ")"");二、js注入实现
先来说说原理吧,当js调用prompt()方法时,WebChromeClient.onJsPrompt()方法会被触发,当js触发Android提供的接口方法时,将该方法的方法名称、参数类型、参数值转成json,然后通过prompt方法传递给android端,android端解析json并通过反射执行对应的方法,同时也支持执行匿名回调。
整个流程比较复杂,看图:
为WebView绑定WebChormeClient监听,在Html加载进度25%时进行js注入(注入的js是根据android提供给js的对象类名动态生成);动态注入的js代码如下:
[javascript] view plain
javascript: (function(b) {
console.log("HostApp initialization begin");var a = {
queue: [],
callback: function() {
var d = Array.prototype.slice.call(arguments, 0);//获取该函数参数并转换为Array数组var c = d.shift();//取得数组第一个元素
var e = d.shift();
this.queue[c].apply(this, d);//新建一个对象 属性名称为取得的c,并将d数组作为他的值。然后将这个对象push到queue数组if(!e) {//e为空的时候,将queue数组属性名称为c的对象删除delete this.queue[c]
}
}
};
//各种赋值,最后都等于同一个函数
a.alert = a.alert = a.alert = a.delayJsCallBack = a.getIMSI = a.getOsSdk = a.goBack = a.overloadMethod = a.overloadMethod = a.passJson2Java = a.passLongType = a.retBackPassJson = a.retJavaObject = a.testLossTime = a.toast = a.toast = function() {var f = Array.prototype.slice.call(arguments, 0);if(f.length < 1) {
throw "HostApp call error, message:miss method name"}
var e = [];
//此段判断,然后赋值
for(var h = 1; h < f.length; h++) {
var c = f[h];
var j = typeof c;
e[e.length] = j;
if(j == "function") {
var d = a.queue.length;
a.queue[d] = c;
f[h] = d
}
}
//将匿名对象{method: f.shift(),types: e,args: f}转换成json字符串并用浏览器弹出确认可输入框,然后取得输入框的值json序列化为js对象var g = JSON.parse(prompt(JSON.stringify({method: f.shift(),
types: e,
args: f
})));
if(g.code != 200) {
throw "HostApp call error, code:" + g.code + ", message:" + g.result}
return g.result
};
//获取a的属性值,然后循环
Object.getOwnPropertyNames(a).forEach(function(d) {var c = a[d];
//判断赋值
if(typeof c === "function" && d !== "callback") {a[d] = function() {
//concat 连接两个数组
return c.apply(a, [d].concat(Array.prototype.slice.call(arguments, 0)))}
}
});
b.HostApp = a;
console.log("HostApp initialization end")})(window);//闭包函数默认执行,然后赋给window。这样window.b就可以执行了 b.HostApp就是执行a的内容,但是a具体处理逻辑不对外开放,避免外部污染a内部逻辑代码不难,可以自行理解,其中回调函数被封装在了a对象里面,确保android端可以通过webview.loadUrl()执行回调。
android端回调js代码如下:
[javascript] view plain
javascript:HostApp.callback(0, 0 ,"call back haha");android提供的每一个js方法都对应一个JsCallback对象,android就可以通过JsCallback对象来生成并执行回调js的代码。
三、优缺点
a.第一种方式不安全,不添加addJavascriptInterface,甚至默认false,在低于API17的WebView上默认添加"SearchBoxJavaBridge_"到mJavaScriptObjects中。这样就有可能通过用户信任的客户端获取SD卡的数据;b.第一种方式必须要API大于等于17才能使用
c.第一种方式当有js回调函数需要android端执行时,都需要将匿名回调函数赋值给全局函数才能供android端回调,增加了js和android端通信的封装层的低效代码量;而第二种方式则是通过动态注入js的方式则非常方便。
d.第二种方式也有一定限制,比如android提供的方法必须是static修饰的,且方法第一个参数必须为WebView,不过这不影响使用。

阅读全文

与androidjsprompt相关的资料

热点内容
js调用外部js 浏览:273
苹果手机照片后期软件 浏览:333
linux自动备份oracle数据库 浏览:447
ios重启app的代码 浏览:565
装了win10文件加锁打不开 浏览:713
苹果电脑怎么新建一个pdf的文件 浏览:379
wps显示word不是一个有效文件 浏览:48
凯立德地图升级工具 浏览:474
linux系统参看log 浏览:416
用手机设置无线密码是多少 浏览:829
销售季度绩效考核怎么体现数据 浏览:335
c盘的文件删除不了 浏览:589
智力app哪个最好用 浏览:203
分析程序的目的 浏览:346
数据线插头用多少度锡丝 浏览:666
怎么用app查看社保卡余额 浏览:374
苹果手机无线网络信号不好 浏览:383
ue4材质中文教程 浏览:689
打开附带文件在图层 浏览:567
mfc怎么删除数据库 浏览:468

友情链接