栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

go读取静态文件.html、css、js404问题

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

go读取静态文件.html、css、js404问题

go读取静态文件.html、css、js404问题
  • 简单项目的静态资源404问题
  • vue-element-template打包生成的静态资源404问题

本篇博客分两种情况来解决golang项目访问静态资源404问题,第一种是自己将静态页面手动创建或者复制到golang项目中。第二种情况是采用第三方框架vue-elementui-template打包生成的文件静态资源404问题

简单项目的静态资源404问题

问题

运行golang项目后,打开index.html页面后各种js、css加载404问题。不多比比,直接上代码。

test1.go

package main

import (
	"fmt"
	"html"
	"html/template"
	"log"
	"net/http"
	"time"
)

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("index.html")

	if err != nil {
		log.Println(err)
	}

	err = t.Execute(w, nil)

	if err != nil {
		log.Println(err)

	}
}


var count int = 1

func Task(w http.ResponseWriter, r *http.Request) {
	fmt.Printf(" ------ here is Task[%d] ------- n", count)
	defer r.Body.Close()
 
	// 模拟延时
	time.Sleep(time.Second * 2)
 
	fmt.Fprintf(w, "Response.No.%d: Your request is %qnn", count, html.EscapeString(r.URL.Path))
	count++
	answer := `{"status:":"OK"}`
	w.Write([]byte(answer))
}


func Task1(w http.ResponseWriter, r *http.Request) {
	fmt.Printf(" ------ here is Task1[%d] ------- n", count)
	defer r.Body.Close()
 
	// 模拟延时
	time.Sleep(time.Second * 2)
 
	fmt.Fprintf(w, "Response.No[%d]: Your request is %qnn", count, html.EscapeString(r.URL.Path))
	count++
	answer := `{"status:":"OK"}`
	w.Write([]byte(answer))
}


func main() {

	// 调用后台接口
	http.HandleFunc("/hello/world", Task)
	http.HandleFunc("/hello/world1", Task1)
	// 启动静态文件服务
	http.Handle("/template/", http.StripPrefix("/template/", http.FileServer(http.Dir("template")))) 
	http.Handle("/libs/", http.StripPrefix("/libs/", http.FileServer(http.Dir("libs"))))
	
	http.HandleFunc("/index", IndexHandler)
	fmt.Println("服务端口:8000") //控制台输出信息

	err := http.ListenAndServe(":8000", nil) //设置监听的端口

	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

解释1:go语言中的http.HandleFunc("/index", IndexHandler)相当于,前端访问接口index,后端去调用方法IndexHandler。
相当于java的

@RequestMapping("/index")
public void IndexHandler() {
	// 在此,怀念我那逝去的java
}

等价于go中的

http.HandleFunc("/index", IndexHandler)

项目结构

index.html代码




  
  
  
  


  
class="mybtn">也无风雨、也无晴 get请求 Button

Try Element

运行

go run test1.go

其中蓝色字体是为了验证不同文件夹下的css的引用

点击下载项目完整代码

vue-element-template打包生成的静态资源404问题

上面的项目是自己手动创建的静态页面和js,html页面里对于js、css的引用都是人为可控的。但是如果是使用的第三方框架,如vue-elemen-template,因为浏览器是不认识.vue文件的,那么开发完成后是将vue等打包成浏览器能解析的js、css、html等文件。打包生成的.html里对于js等的引用路径是可以修改的,但是太过于麻烦,有兴趣的道友可以自行百度,我这里就按它默认生成的资源,然后在go代码里去解决404问题。

工欲善其事,必先利其器。既然是404那么就是静态资源没有加载到,我们就需要了解go是怎么加载静态资源的。那就是函数http.StripPrefix与http.FileServer

我们来看看这行代码

http.Handle("/template/", http.StripPrefix("/template/", http.FileServer(http.Dir("template")))) 

以上http.Handle("/template/",就是相当于一个请求,当前端发起http:www.xxx.com:9527/template时,会进入该方法。即
相当于java的

@RequestMapping("/index")
public void IndexHandler() {
	// 在此,怀念我那逝去的java
}

等价于go中的

http.HandleFunc("/index", IndexHandler)

然后我们看http.StripPrefix方法,它就是拦截请求中含有/template/前缀的资源请求,然后将该前缀替换成http.Dir(“template”)中的template。

http.Dir表示文件的起始路径,空即为当前路径。调用Open方法时,传入的参数需要在前面拼接上该起始路径得到实际文件路径。

http.FileServer的返回值类型是http.Handler,所以需要使用Handle方法注册处理器。http.FileServer将收到的请求路径传给http.Dir的Open方法打开对应的文件或目录进行处理。 在上面的程序中,如果请求路径为/static/hello.html,那么拼接http.Dir的起始路径.,最终会读取路径为./static/hello.html的文件。

有时候,我们想要处理器的注册路径和http.Dir的起始路径不相同。有些工具在打包时会将静态文件输出到public目录中。 这时需要使用http.StripPrefix方法,该方法会将请求路径中特定的前缀去掉,然后再进行处理:如下代码

package main
 
import (
  "log"
  "net/http"
)
 
func main() {
  mux := http.NewServeMux()
  mux.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./public"))))
 
 
  server := &http.Server {
    Addr: ":8080",
    Handler: mux,
  }
 
  if err := server.ListenAndServe(); err != nil {
    log.Fatal(err)
  }
}

这时,请求localhost:8080/static/hello.html将会返回./public/hello.html文件。 路径/static/index.html经过处理器http.StripPrefix去掉了前缀/static得到/index.html,然后又加上了http.Dir的起始目录./public得到文件最终路径./public/hello.html。
如果你就想请求static下的文件,那么就将http.Dir中写static即可。
简单点理解就是将含有static的请求拦截,并将http.Dir中的路径替换掉http.StripPrefix中的路径,拼接成新的文件路径然后相应给前端。

好了,大致原理我们明白了。那么实际操作一下,看我的代码。
目录结构

dist文件夹结构

index.html页面的代码

,我们可以看到它打包生成后对静态文件的应用全部都是以static开头的,那么在浏览器加载静态资源的时候,请求的路径就是

GET http://127.0.0.1:8090/static/js/app.js


这样的请求路径显然是请求不到数据的,那么我们只需要将http://127.0.0.1:8090/static/js/app.js的请求路径修改为
http://127.0.0.1:8090/src/views/vue-element-template/dist/static/js/app.js即可。也就是我们上面分析的将static的请求拦截并且替换路径即可,
我们的项目文件路径是/src/views/vue-element-template/dist/static/
就一行代码,

// 启动静态文件服务
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./src/views/vue-element-template/dist/static/")))) 

vscode里切换到main.go所在的路径,运行

go run main.go

再次打开浏览器,问题解决


此处贴出部分代码
main.go

package main

import (
	"fmt"
	"engine_stability_platform/src/app/httpServer"
)
 
func main() {
	fmt.Println("main.....")
	httpServer.Start()
}

httpServer.go

package httpServer

import (
	"fmt"
	. "fmt"
	"html"
	"html/template"
	"net/http"
)


func IndexHandler(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("src/views/vue-element-template/dist/index.html")
	if err != nil {
		fmt.Println(err)
	}

	err = t.Execute(w, nil)
	if err != nil {
		fmt.Println(err)
	}
}
var count int = 1
// 测试demo
func Task(w http.ResponseWriter, r *http.Request) {
	Printf(" ------ here is Task[%d] ------- n", count)
	Fprintf(w, "Response.No.%d: Your request is %qnn", count, html.EscapeString(r.URL.Path))
	count++
	answer := `{"status:":"OK"}`
	w.Write([]byte(answer))
}
 
func Task1(w http.ResponseWriter, r *http.Request) {
	Printf(" ------ here is Task1[%d] ------- n", count)
	Fprintf(w, "Response.No[%d]: Your request is %qnn", count, html.EscapeString(r.URL.Path))
	count++
	answer := `{"status:":"OK"}`
	w.Write([]byte(answer))
}
var server *http.Server

func Start() {
	Println("===== This is http server =====")

	mux := http.NewServeMux()
	mux.HandleFunc("/hello/world", Task)
	mux.HandleFunc("/hello/world1", Task1)
	// 启动静态文件服务
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./src/views/vue-element-template/dist/static/"))))
	mux.HandleFunc("/index", IndexHandler)

	if server != nil {
		// 避免重复start server 端口泄露
		server.Close()
	}
	// 设置服务器
	server := &http.Server{
		Addr: "127.0.0.1:8090",
		Handler: mux,
	}
	// 设置服务器监听端口
	server.ListenAndServe()
}

index.html



  
    
    
    
    
    Vue Admin Template
  
  
    
    

补充:vue-element-template生成的资源文件夹也可以在vue.config.js里进行更改

点击下载项目完整代码

参考文章:https://blog.csdn.net/whatday/article/details/109747385?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242.1

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/944261.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号