fix: allowUniversalAccessFromFileURLs(CORS审查)

This commit is contained in:
LukeMackin
2026-07-22 21:13:39 +08:00
parent d851c25edf
commit 5cf0cf40e3
4 changed files with 104 additions and 8 deletions

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,user-scalable=no">
<title>Yuzu GCA</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:system-ui;background:#0f172a;color:#e2e8f0;padding:16px}
h1{font-size:20px;color:#38bdf8;margin-bottom:4px}
.info{color:#94a3b8;font-size:12px;margin-bottom:16px}
.card{background:#1e293b;border-radius:8px;padding:16px;margin:12px 0}
.card-title{font-size:13px;color:#94a3b8;margin-bottom:8px}
.btn{display:block;width:100%;padding:14px;margin:8px 0;border:none;border-radius:8px;font-size:15px;cursor:pointer;color:#fff}
.btn-blue{background:#1e40af}
.btn-green{background:#15803d}
.btn-red{background:#991b1b}
.input{display:block;width:100%;padding:12px;margin:8px 0;border:none;border-radius:8px;font-size:14px;background:#0f172a;color:#e2e8f0}
.log{background:#0a0f1a;padding:12px;border-radius:8px;margin-top:8px;max-height:200px;overflow-y:auto;font-size:11px;white-space:pre-wrap;color:#22c55e;font-family:monospace}
.tab{display:inline-block;padding:8px 16px;margin-right:4px;border-radius:6px 6px 0 0;background:#1e293b;color:#64748b;font-size:13px;cursor:pointer}
.tab-on{background:#1e40af;color:#fff}
</style></head><body>
<h1>Yuzu GCA</h1>
<div class="info">Self-contained MCP Client</div>
<div>
<span class="tab tab-on" onclick="switchTab('exec')">Exec</span>
<span class="tab" onclick="switchTab('files')">Files</span>
<span class="tab" onclick="switchTab('sysinfo')">SysInfo</span>
</div>
<div class="card" id="tab-exec">
<div class="card-title">Execute Command (Gateway)</div>
<input class="input" id="gwUrl" placeholder="Gateway URL (http://x.x.x.x:3000)" value="http://10.1.0.17:3000">
<input class="input" id="cmd" placeholder="Command (e.g. ls, whoami, dir)">
<button class="btn btn-blue" onclick="execCmd()">Execute</button>
<div class="log" id="log-exec"></div>
</div>
<div class="card" id="tab-files" style="display:none">
<div class="card-title">List Files (Gateway)</div>
<input class="input" id="path" placeholder="Path (e.g. /sdcard, .)" value=".">
<button class="btn btn-blue" onclick="listFiles()">List</button>
<div class="log" id="log-files"></div>
</div>
<div class="card" id="tab-sysinfo" style="display:none">
<div class="card-title">System Info (Local)</div>
<button class="btn btn-blue" onclick="showSysInfo()">Refresh</button>
<div class="log" id="log-sysinfo"></div>
</div>
<script>
function switchTab(t){
document.querySelectorAll('.tab').forEach(e=>e.classList.toggle('tab-on',false));
document.querySelectorAll('.card').forEach(e=>e.style.display='none');
document.getElementById('tab-'+t).style.display='block';
event.target.classList.toggle('tab-on',true);
}
function log(id,msg){
var l=document.getElementById(id);
l.innerText+=msg+'\n';l.scrollTop=l.scrollHeight;
}
function execCmd(){
var gw=document.getElementById('gwUrl').value,c=document.getElementById('cmd').value;
var id='log-exec';document.getElementById(id).innerText='';
log(id,'$ '+c);
fetch(gw+'/tools/exec',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({command:c})})
.then(r=>r.json()).then(d=>log(id,d.stdout||d.stderr||JSON.stringify(d)))
.catch(e=>log(id,'ERR: '+e.message));
}
function listFiles(){
var gw=document.getElementById('gwUrl').value,p=document.getElementById('path').value;
var id='log-files';document.getElementById(id).innerText='';
log(id,'ls '+p);
fetch(gw+'/tools/file_list',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p})})
.then(r=>r.json()).then(d=>{
if(d.entries){d.entries.forEach(e=>log(id,(e.type==='dir'?'[DIR]':'')+' '+e.name+(e.size?' ('+e.size+'B)':'')))}
else log(id,JSON.stringify(d));
}).catch(e=>log(id,'ERR: '+e.message));
}
function showSysInfo(){
var id='log-sysinfo';document.getElementById(id).innerText='';
log(id,'Platform: '+navigator.platform);
log(id,'UserAgent: '+navigator.userAgent);
log(id,'Online: '+navigator.onLine);
if(typeof Android!=='undefined'){log(id,'Bridge: YES');log(id,'Files: '+Android.fetchText('version.txt'))}
else log(id,'Bridge: NO');
}
</script></body></html>

View File

@@ -1,12 +1,17 @@
package dev.yuzu.gca package dev.yuzu.gca
import com.facebook.react.ReactActivity import android.os.Bundle
import com.facebook.react.ReactActivityDelegate import android.webkit.WebView
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled import androidx.appcompat.app.AppCompatActivity
import com.facebook.react.defaults.DefaultReactActivityDelegate
class MainActivity : ReactActivity() { class MainActivity : AppCompatActivity() {
override fun getMainComponentName(): String = "main" override fun onCreate(savedInstanceState: Bundle?) {
override fun createReactActivityDelegate(): ReactActivityDelegate = super.onCreate(savedInstanceState)
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) WebView(this).apply {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.allowUniversalAccessFromFileURLs = true
loadUrl("file:///android_asset/index.html")
}.also { setContentView(it) }
}
} }

BIN
s-final.png Normal file

Binary file not shown.

BIN
s2.png

Binary file not shown.