diff --git a/frontend/src/components/builtin/Browser.vue b/frontend/src/components/builtin/Browser.vue
index 4dcd0dc..bf75b19 100644
--- a/frontend/src/components/builtin/Browser.vue
+++ b/frontend/src/components/builtin/Browser.vue
@@ -1,113 +1,80 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
\ No newline at end of file
diff --git a/godo/cmd/main.go b/godo/cmd/main.go
index 6028077..64b5df4 100644
--- a/godo/cmd/main.go
+++ b/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))
diff --git a/godo/go.mod b/godo/go.mod
index 96f5a2b..13fc7a8 100644
--- a/godo/go.mod
+++ b/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
)
diff --git a/godo/go.sum b/godo/go.sum
index be86de1..1d17612 100644
--- a/godo/go.sum
+++ b/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=
diff --git a/godo/store/ie.go b/godo/store/ie.go
new file mode 100644
index 0000000..163d2c6
--- /dev/null
+++ b/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)
+
+ // 插入 标签
+ baseTag := fmt.Sprintf("", url)
+ html = strings.Replace(html, "
", fmt.Sprintf("%s", baseTag), 1)
+ // 过滤掉可能引起弹窗的脚本
+ re := regexp.MustCompile(`(window\.open)\(.*?\);`)
+ html = re.ReplaceAllString(html, "")
+ // 移除或修改 a 标签的 target="_blank" 属性
+ reA := regexp.MustCompile(`(]*?)\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)
+// }