请教一个同源策略的问题

20 小时 33 分钟前
 elinktek

需要 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 = 'test@qq.com'; 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();
        }
    }
}

求大神指点,谢谢

512 次点击
所在节点    程序员
5 条回复
shadowyue
20 小时 24 分钟前
没看懂,怎么突然冒出来个 test01
okakuyang
20 小时 13 分钟前
AI 的回答看不出与你的问题有啥联系。 不过因为同源问题拿不到 iframe 的内容可以理解
rabbbit
20 小时 6 分钟前
没懂,不过 iframe 交互可以试试 postMessage
chenluo0429
20 小时 5 分钟前
从你的代码里面没看到 iframe 啊,网页就是在 webview 中加载的,哪来的同源
elinktek
18 小时 59 分钟前
页面的源碼是這個
```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>

```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1156378

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX