需要 android 程序自动注入 js 表单信息,用户名密码,然后提交 网址是: https://aa.bb.buzz/test 实际网页的源码是 https://aa.bb.buzz/test/frame.html 我写的是 webView.loadUrl("https://aa.bb.buzz/test/frame.html"); 现在要求必须写成 webView.loadUrl("https://aa.bb.buzz/test");我查了 AI 说不能直接操作这个网址
AI 的解释: 为什么会失败? 同源策略 (Same-Origin Policy):
一个网页的“源”由协议、域名和端口号共同决定。
父页面 URL: https://aaa.buzz/test/,其源是 https://aaa.buzz 。
iframe URL: https://test01.aaa.buzz/test/frame.html ,其源是 https://test01.aaa.buzz 。
尽管这两个域名都属于 aaa.buzz ,但 test01.aaa.buzz 是一个不同的子域名,因此根据同源策略,它们被视为不同的源。
出于安全考虑,浏览器严格禁止一个源的脚本(例如注入到父页面的 JavaScript )访问另一个源的 DOM 内容(例如 iframe 里的表单元素)。这正是您日志中显示的 SecurityError 错误的原因。
shouldOverrideUrlLoading 的局限性:
您尝试使用 shouldOverrideUrlLoading 方法来拦截 iframe 的加载,但这通常只适用于主页面的导航事件(如用户点击链接或重定向)。WebView 加载 <iframe> 内部内容的行为,通常不会触发这个回调。因此,您的代码无法在 iframe 加载时进行拦截并跳转。
目前写的关键代码:
public class MainActivity extends AppCompatActivity {
private WebView webView;
private static final String TAG = "WebViewApp";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
// 启用 JavaScript
webView.getSettings().setJavaScriptEnabled(true);
// 绑定 JavaScript 接口
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
// 设置 WebViewClient ,监听页面加载完成
webView.setWebViewClient(new MyWebViewClient());
// 直接加载包含表单的 URL
webView.loadUrl("https://test01.aaa.buzz/test/frame.html");
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d(TAG, "Page finished loading: " + url);
// 注入一个健壮的 JavaScript 代码,使用更通用的方法查找元素,并将代码压缩为单行
String js = "(function() { function waitForElementsAndSubmit() { var inputs = document.getElementsByTagName('input'); var buttons = document.getElementsByTagName('button'); var usernameInput = null; var emailInput = null; var submitButton = null; var inputCount = 0; for (var i = 0; i < inputs.length; i++) { if (inputs[i].type === 'text') { if (!usernameInput) { usernameInput = inputs[i]; } else { emailInput = inputs[i]; break; } } } for (var i = 0; i < buttons.length; i++) { if (buttons[i].type === 'submit' || buttons[i].id === 'submit') { submitButton = buttons[i]; break; } } if (usernameInput && emailInput && submitButton) { console.log('找到所有元素,开始填写和提交。'); usernameInput.value = 'test'; emailInput.value = '[email protected]'; var form = submitButton.closest('form'); if (form) { form.submit(); } else { submitButton.click(); } setTimeout(function() { Android.showToast('表单已自动提交。'); }, 1000); } else { console.log('未找到元素,继续等待...'); setTimeout(waitForElementsAndSubmit, 200); } } waitForElementsAndSubmit(); })();";
view.evaluateJavascript(js, null);
}
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
求大神指点,谢谢
![]() |
1
shadowyue 13 天前
没看懂,怎么突然冒出来个 test01
|
2
okakuyang 13 天前
AI 的回答看不出与你的问题有啥联系。 不过因为同源问题拿不到 iframe 的内容可以理解
|
![]() |
3
rabbbit 13 天前
没懂,不过 iframe 交互可以试试 postMessage
|
4
chenluo0429 13 天前 via Android
从你的代码里面没看到 iframe 啊,网页就是在 webview 中加载的,哪来的同源
|
5
elinktek OP 页面的源碼是這個
```HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home Page</title> </head> <body> <iframe name="test_frame" title="这是一个用于测试的内嵌页面" src="https://test01.aaa.buzz/test/frame.html" frameborder="0" style="width: 100%; height: 100%;"></iframe> </body> </html> ``` |
6
elinktek OP 原来问题解决了。现在有新问题
问一下有人适配过小米手机吗?,这个 demo 用真机 android11 和 android16 ,虚拟机 android15 都测试正常,对方说小米的 android15 提交没有弹窗,我问 AI 小米是有一些特殊限制,我手边没有小米手机,谁有遇到类似的问题吗? 以下是 AI 回答: ```JAVA 小米的系统( MIUI )确实有一些特殊的系统设定,可能会导致你的应用行为与其他原生 Android 设备或虚拟机有所不同,尤其是在涉及 WebView 和后台任务时。 你遇到的问题很可能与以下几个方面有关: 1. MIUI 的进程和内存管理 MIUI 的后台进程清理非常激进。它可能会在应用进入后台或屏幕关闭时,更早地杀死进程或暂停 WebView 的活动,从而影响 setTimeout 或其他异步任务的执行。如果用户在表单自动提交完成前切换到其他应用,MIUI 可能直接中止了 WebView 的 JavaScript 引擎。 2. WebView 行为差异 虽然 Android 15 虚拟机和真机都基于相同的 Chromium 内核,但一些 OEM 可能会对 WebView 的底层行为进行微调,例如渲染时机、资源加载优先级或安全策略。 加载时机:onPageFinished 回调在某些设备上可能比在其他设备上更早触发。对于你的网页,主页面( https://sophiadesign.buzz/test/)的 onPageFinished 可能会在 iframe 中的内容完全加载完成之前就被调用。如果你的 JavaScript 注入得太早,它可能找不到 iframe 中的元素。 安全策略: 小米可能会对 JavaScript 在 WebView 中的行为有更严格的沙盒或安全限制,特别是当它尝试操作来自不同域的 iframe 内容时。 针对小米设备问题的解决方案 你之前使用的代码注入逻辑,虽然在大多数设备上有效,但可能存在一个**“竞态条件”( race condition )**。也就是说,JavaScript 注入和 iframe 内容加载完成之间存在时间差。 最稳妥的解决办法是直接加载表单页面,而不是通过父页面和 iframe 。 ``` |