请教一个同源策略的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
elinktek
V2EX    程序员

请教一个同源策略的问题

  •  
  •   elinktek 45 天前 1347 次点击
    这是一个创建于 45 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需要 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(); } } } 

    求大神指点,谢谢

    6 条回复    2025-09-03 18:02:56 +08:00
    shadowyue
        1
    shadowyue  
       45 天前
    没看懂,怎么突然冒出来个 test01
    okakuyang
        2
    okakuyang  
       45 天前
    AI 的回答看不出与你的问题有啥联系。 不过因为同源问题拿不到 iframe 的内容可以理解
    rabbbit
        3
    rabbbit  
       45 天前
    没懂,不过 iframe 交互可以试试 postMessage
    chenluo0429     4
    chenluo0429  
       45 天前 via Android
    从你的代码里面没看到 iframe 啊,网页就是在 webview 中加载的,哪来的同源
    elinktek
        5
    elinktek  
    OP
       45 天前
    页面的源是
    ```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>

    ```
    elinktek
        6
    elinktek  
    OP
       43 天前
    原来问题解决了。现在有新问题
    问一下有人适配过小米手机吗?,这个 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 。
    ```
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3801 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 04:14 PVG 12:14 LAX 21:14 JFK 00:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86