Browse Source

Merge branch 'master' of https://gitee.com/godoos/godoos

master
prr 6 months ago
parent
commit
942b0e815b
  1. 127
      frontend/src/components/builtin/Browser.vue
  2. 5
      godo/cmd/main.go
  3. 8
      godo/go.mod
  4. 7
      godo/go.sum
  5. 124
      godo/store/ie.go

127
frontend/src/components/builtin/Browser.vue

@ -1,113 +1,80 @@
<template>
<div class="outer win11-theme">
<div class="controls">
<button class="change-button" @click="goBack" :disabled="!canGoBack">
<svg
t="1632984723698"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="10100"
width="20"
height="20"
>
<path
d="M862.485 481.154H234.126l203.3-203.3c12.497-12.497 12.497-32.758 0-45.255s-32.758-12.497-45.255 0L135.397 489.373c-12.497 12.497-12.497 32.758 0 45.254l256.774 256.775c6.249 6.248 14.438 9.372 22.627 9.372s16.379-3.124 22.627-9.372c12.497-12.497 12.497-32.759 0-45.255l-203.3-203.301h628.36c17.036 0 30.846-13.81 30.846-30.846s-13.81-30.846-30.846-30.846z"
fill=""
p-id="10101"
></path>
</svg>
</button>
<button class="change-button" @click="goForward" :disabled="!canGoForward">
<svg
t="1632984737821"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="10249"
width="20"
height="20"
>
<path
d="M885.113 489.373L628.338 232.599c-12.496-12.497-32.758-12.497-45.254 0-12.497 12.497-12.497 32.758 0 45.255l203.3 203.3H158.025c-17.036 0-30.846 13.811-30.846 30.846 0 17.036 13.811 30.846 30.846 30.846h628.36L583.084 746.147c-12.497 12.496-12.497 32.758 0 45.255 6.248 6.248 14.438 9.372 22.627 9.372s16.379-3.124 22.627-9.372l256.775-256.775a31.999 31.999 0 0 0 0-45.254z"
fill=""
p-id="10250"
></path>
</svg>
</button>
<button class="change-button" @click="refreshPage">
<svg
t="1632984867128"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1857"
width="15"
height="15"
>
<path
d="M927.999436 531.028522a31.998984 31.998984 0 0 0-31.998984 31.998984c0 51.852948-10.147341 102.138098-30.163865 149.461048a385.47252 385.47252 0 0 1-204.377345 204.377345c-47.32295 20.016524-97.6081 30.163865-149.461048 30.163865s-102.138098-10.147341-149.461048-30.163865a385.47252 385.47252 0 0 1-204.377345-204.377345c-20.016524-47.32295-30.163865-97.6081-30.163865-149.461048s10.147341-102.138098 30.163865-149.461048a385.47252 385.47252 0 0 1 204.377345-204.377345c47.32295-20.016524 97.6081-30.163865 149.461048-30.163865a387.379888 387.379888 0 0 1 59.193424 4.533611l-56.538282 22.035878A31.998984 31.998984 0 1 0 537.892156 265.232491l137.041483-53.402685a31.998984 31.998984 0 0 0 18.195855-41.434674L639.723197 33.357261a31.998984 31.998984 0 1 0-59.630529 23.23882l26.695923 68.502679a449.969005 449.969005 0 0 0-94.786785-10.060642c-60.465003 0-119.138236 11.8488-174.390489 35.217667a449.214005 449.214005 0 0 0-238.388457 238.388457c-23.361643 55.252253-35.22128 113.925486-35.22128 174.390489s11.8488 119.138236 35.217668 174.390489a449.214005 449.214005 0 0 0 238.388457 238.388457c55.252253 23.368867 113.925486 35.217667 174.390489 35.217667s119.138236-11.8488 174.390489-35.217667A449.210393 449.210393 0 0 0 924.784365 737.42522c23.368867-55.270316 35.217667-113.925486 35.217667-174.390489a31.998984 31.998984 0 0 0-32.002596-32.006209z"
fill=""
p-id="1858"
></path>
</svg>
</button>
<input
class="url-input"
v-model="urlinput"
@keydown.enter="changeUrl"
placeholder="Enter URL"
/>
<el-icon class="change-button" @click="goBack" :disabled="!canGoBack">
<ArrowLeft />
</el-icon>
<el-icon class="change-button" @click="goForward" :disabled="!canGoForward">
<ArrowRight />
</el-icon>
<el-icon class="change-button" @click="refreshPage">
<Refresh />
</el-icon>
<input class="url-input" v-model="urlinput" @keydown.enter="changeUrl" placeholder="Enter URL" />
</div>
<iframe class="webframe" ref="iframeRef" :src="urlsrc"></iframe>
<!-- <div class="webframe" v-html="webContent"></div> -->
<iframe
class="webframe"
:srcdoc="webContent"
frameborder="0"
allowfullscreen
></iframe>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted } from 'vue';
const urlinput = ref('https://wap.baidu.com/');
const urlsrc = ref('https://wap.baidu.com/');
const iframeRef:any = ref(null);
let canGoBack = false;
let canGoForward = false;
import { getSystemKey } from '@/system/config';
const urlinput = ref('https://godoos.com/');
const webContent = ref('');
const canGoBack = ref(false);
const canGoForward = ref(false);
async function callApi(endpoint: string) {
const apiUrl = await getSystemKey('apiUrl');
let fetchUrl = `${apiUrl}/ie/${endpoint}?url=${encodeURIComponent(urlinput.value)}`
const response = await fetch(fetchUrl);
if (response.ok) {
const data = await response.text();
webContent.value = data;
} else {
console.log('Network response was not ok');
}
}
function updateNavigationButtons() {
canGoBack = window.history.length > 1;
canGoForward = window.history.length < window.history.state?.length;
canGoBack.value = window.history.length > 1;
canGoForward.value = window.history.length < window.history.state?.length;
}
function goBack() {
if (canGoBack) {
window.history.back();
if (canGoBack.value) {
callApi('back');
}
}
function goForward() {
if (canGoForward) {
window.history.forward();
if (canGoForward.value) {
callApi('forward');
}
}
function refreshPage() {
iframeRef.value.contentWindow?.location.reload();
callApi('refresh');
}
function changeUrl() {
const protocolAdded = /^(http|https):\/\//.test(urlinput.value) ? urlinput.value : `https://${urlinput.value}`;
urlsrc.value = protocolAdded;
urlinput.value = protocolAdded;
callApi('navigate');
}
onMounted(() => {
window.addEventListener('popstate', updateNavigationButtons);
updateNavigationButtons();
callApi('navigate');
});
onUnmounted(() => {
@ -115,7 +82,6 @@ onUnmounted(() => {
});
</script>
<style scoped>
.win11-theme {
display: flex;
@ -168,5 +134,6 @@ onUnmounted(() => {
flex: 1;
width: 100%;
border: none;
overflow-y: auto; /* 添加滚动条 */
}
</style>

5
godo/cmd/main.go

@ -144,6 +144,11 @@ func OsStart() {
// router.Handle("/model/voice", http.MethodPost, voice.UploadHandler)
// router.Handle("/model/tts", http.MethodPost, voice.TtsHandler)
// router.Handle("/model/audio", http.MethodGet, voice.ServeAudio)
ieRouter := router.PathPrefix("/ie").Subrouter()
ieRouter.HandleFunc("/navigate", store.HandleNavigate).Methods(http.MethodGet)
ieRouter.HandleFunc("/back", store.HandleBack).Methods(http.MethodGet)
ieRouter.HandleFunc("/forward", store.HandleForward).Methods(http.MethodGet)
ieRouter.HandleFunc("/refresh", store.HandleRefresh).Methods(http.MethodGet)
distFS, _ := fs.Sub(deps.Frontendassets, "dist")
fileServer := http.FileServer(http.FS(distFS))

8
godo/go.mod

@ -1,6 +1,8 @@
module godo
go 1.22.5
go 1.23
toolchain go1.23.3
require (
github.com/cavaliergopher/grab/v3 v3.0.1
@ -17,6 +19,6 @@ require (
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/sys v0.27.0 // indirect
)

7
godo/go.sum

@ -26,8 +26,9 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -37,8 +38,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

124
godo/store/ie.go

@ -0,0 +1,124 @@
package store
import (
"fmt"
"io"
"net/http"
"regexp"
"strings"
)
type PageState struct {
URL string `json:"url"`
History []string
Index int
}
var pageState = &PageState{}
func fetchPageContent(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
html := string(body)
// 插入 <base> 标签
baseTag := fmt.Sprintf("<base href=\"%s\" />", url)
html = strings.Replace(html, "<head>", fmt.Sprintf("<head>%s", baseTag), 1)
// 过滤掉可能引起弹窗的脚本
re := regexp.MustCompile(`(window\.open)\(.*?\);`)
html = re.ReplaceAllString(html, "")
// 移除或修改 a 标签的 target="_blank" 属性
reA := regexp.MustCompile(`(<a[^>]*?)\s*target\s*=\s*"?_blank"?`)
html = reA.ReplaceAllString(html, "$1")
// 移除 X-Frame-Options 和 Content-Security-Policy 头
resp.Header.Del("X-Frame-Options")
resp.Header.Del("Content-Security-Policy")
return html, nil
}
func HandleNavigate(w http.ResponseWriter, r *http.Request) {
url := r.URL.Query().Get("url")
if url == "" {
http.Error(w, "URL parameter is required", http.StatusBadRequest)
return
}
html, err := fetchPageContent(url)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
pageState.History = append(pageState.History, url)
pageState.Index = len(pageState.History) - 1
pageState.URL = url
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, html)
}
func HandleBack(w http.ResponseWriter, r *http.Request) {
if pageState.Index > 0 {
pageState.Index--
url := pageState.History[pageState.Index]
html, err := fetchPageContent(url)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
pageState.URL = url
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, html)
} else {
http.Error(w, "No more history to go back", http.StatusForbidden)
}
}
func HandleForward(w http.ResponseWriter, r *http.Request) {
if pageState.Index < len(pageState.History)-1 {
pageState.Index++
url := pageState.History[pageState.Index]
html, err := fetchPageContent(url)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
pageState.URL = url
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, html)
} else {
http.Error(w, "No more history to go forward", http.StatusForbidden)
}
}
func HandleRefresh(w http.ResponseWriter, r *http.Request) {
if pageState.URL != "" {
html, err := fetchPageContent(pageState.URL)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, html)
} else {
http.Error(w, "No current URL to refresh", http.StatusForbidden)
}
}
// func main() {
// http.HandleFunc("/navigate", HandleNavigate)
// http.HandleFunc("/back", HandleBack)
// http.HandleFunc("/forward", HandleForward)
// http.HandleFunc("/refresh", HandleRefresh)
//
// http.ListenAndServe(":8080", nil)
// }
Loading…
Cancel
Save