Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 三上悠亚亚洲精品一区,国产网站在线播放,亚洲春色第一页

          整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          http 頁面重定向 redirect

          http 頁面重定向 redirect

          頁面的重定向想必大家都知道,如果你是用過 koa ,那么通過如下代碼,就能讓網(wǎng)頁跳轉(zhuǎn)至指定頁面:

          或者你用過 java 的重定向:

          那么框架內(nèi)部到底是怎么實現(xiàn)頁面重定向的呢?這篇小短文可能會讓你更加清楚其中的一些原理。

          重定向


          概念

          當你在瀏覽器訪問 A 地址時,你會看到瀏覽器會刷新進度條,地址欄被更新為 B 地址。這就是 URL 重定向。

          這樣類似的技術(shù),就是由 Http 協(xié)議定義的。重定向操作是由服務端向客戶端發(fā)送特定的響應狀態(tài)來觸發(fā),這類狀態(tài)有個專門的狀態(tài)碼:3xx ,當瀏覽器接收后,將會進行頁面的重定向,即地址發(fā)生了跳轉(zhuǎn)。


          幾種狀態(tài)碼


          302 和 301 的區(qū)別

          上面列了許多 3xx 的狀態(tài)碼,但平時我們最多用的是 301 和 302,這里就詳細解釋這兩個的區(qū)別:

          301

          永久重定向。如果 A 地址被 301 到 B 地址后,后續(xù)再次請求 A 地址的話,瀏覽器就會默認首次請求 B 地址,不會再有 A 地址的請求。

          等看到第一次訪問 /api/books/111 時,頁面被重定向到 /api/books,瀏覽器發(fā)送兩次請求。但后續(xù)再次請求 /api/books/111 時,直接請求了 /api/books 。

          所以通常該狀態(tài)碼用于網(wǎng)站重構(gòu),告知搜索引擎你以后訪問我 301 重定向的地址。

          302

          相反,302 就是臨時重定向。

          平時我們登陸頁面的授權(quán)跳轉(zhuǎn)都是基于此狀態(tài)碼。因為客戶端訪問的頁面是臨時不可用,滿足了某些條件后,可以繼續(xù)使用。

          對比 301 的請求,能看到兩次 /api/books/222 的請求都被“記錄在案”。

          koa 中的重定向

          來看下 koa 中 response 的 redirect 的重定向源碼:

          能看到在這段重定向的代碼中,分別設置了 location 和 狀態(tài)碼,依靠他們來完成重定向的功能。

          當然我們可以自己簡單的實現(xiàn)一個服務器重定向功能:

          總結(jié)

          如果你只是單純的使用框架的 redirect api,而不清楚其內(nèi)部的原理,可能這篇會幫助你了解更多些。

          畢竟這是 Http 的基礎,會讓你對瀏覽器的重定向有個概念。

          關(guān)于我

          一位“前端工程師”,樂于實踐,并分享前端開發(fā)經(jīng)驗。

          如果有問題或者想法,歡迎各位評論留言,愿大家共同進步。

          關(guān)注【前端雨爸】,查閱更多前端技術(shù)心得。

          package main
          import (
              "crypto/sha1"
              "encoding/hex"
              "fmt"
              "io"
              "io/ioutil"
              "net/http"
              "os"
              "strconv"
          )
          //加載首頁的頁面
          func indexHandler(w http.ResponseWriter, r *http.Request) {
              data, err :=ioutil.ReadFile("./static/index.html")
              if err !=nil {
                  io.WriteString(w, "internel server error")
                  return
              }
              io.WriteString(w, string(data))
          }
          //加載首頁的第二種方式(頁面跳轉(zhuǎn))
          func homeHandler(w http.ResponseWriter, r *http.Request) {
              http.Redirect(w, r, "/static/index.html", http.StatusFound)
              return
          }
          //接收表單參數(shù)
          func userHandler(w http.ResponseWriter, r *http.Request) {
              r.ParseForm() //解析參數(shù),默認是不會解析的
              if r.Method=="GET" { //GET請求的方法
                  username :=r.Form.Get("username") //必須使用雙引號, 注意: 這里的Get 不是指只接收GET請求的參數(shù), 而是獲取參數(shù)
                  password :=r.Form.Get("password")
                  // limitCnt, _ :=strconv.Atoi(r.Form.Get("limit")) //字符串轉(zhuǎn)整數(shù)的接收方法
                  //io.WriteString(w, username+":"+password)
                  w.Write([]byte(username + ":" + password))
              } else if r.Method=="POST" { //POST請求的方法
                  username :=r.Form.Get("username") //必須使用雙引號, 注意: POST請求, 也是用Get方法來接收
                  password :=r.Form.Get("password")
                  //io.WriteString(w, username+":"+password)
                  w.Write([]byte(username + ":" + password))
              }
          }
          //文件上傳
          func uploadHandler(w http.ResponseWriter, r *http.Request) {
              r.ParseForm() //解析參數(shù),默認是不會解析的
              if r.Method=="GET" { //GET請求的方法
              data, err :=ioutil.ReadFile("./static/upload.html")
              if err !=nil {
              io.WriteString(w, "internel server error")
              return
              }
              io.WriteString(w, string(data))
              } else if r.Method=="POST" { //POST請求的方法
              // 接收文件流及存儲到本地目錄
              file, head, err :=r.FormFile("image") //接收文件域的方法
              if err !=nil {
              fmt.Printf("Failed to get data, err:%s\n", err.Error())
              return
              }
              defer file.Close()
              newFile, err :=os.Create("C:/tmp/" + head.Filename) //創(chuàng)建文件
              if err !=nil {
              fmt.Printf("Failed to create file, err:%s\n", err.Error())
              return
              }
              defer newFile.Close()
              FileSize, err :=io.Copy(newFile, file) //拷貝文件
              if err !=nil {
              fmt.Printf("Failed to save data into file, err:%s\n", err.Error())
              //http.Redirect(w, r, "/static/index.html", http.StatusFound) //重定向的方法
              return
              }
              //文件的sha1的值
              io.WriteString(w, "上傳成功"+"\r\n文件的大小:"+strconv.FormatInt(FileSize, 10)+"\r\n文件的sha1:"+fileSha1(newFile)) //int64轉(zhuǎn)換成string
              }
          }
          // downloadHandler : 文件下載接口
          func downloadHandler(w http.ResponseWriter, r *http.Request) {
              r.ParseForm()
              filename :=r.Form.Get("filename")
              f, err :=os.Open("C:/tmp/" + filename)
              if err !=nil {
                  w.WriteHeader(http.StatusInternalServerError)
                  return
              }
              defer f.Close()
              data, err :=ioutil.ReadAll(f) //ReadAll從r讀取數(shù)據(jù)直到EOF或遇到error
              if err !=nil {
                  w.WriteHeader(http.StatusInternalServerError)
                  return
              }
              w.Header().Set("Content-Type", "application/octect-stream")
              w.Header().Set("content-disposition", "attachment; filename=\""+filename+"\"")
              w.Write(data)
          }
          //獲取文件的sha1值
          func fileSha1(file *os.File) string {
              _sha1 :=sha1.New() //返回一個新的使用SHA1校驗的hash.Hash接口
              io.Copy(_sha1, file) //將src的數(shù)據(jù)拷貝到dst,直到在src上到達EOF或發(fā)生錯誤。返回拷貝的字節(jié)數(shù)和遇到的第一個錯誤。
              return hex.EncodeToString(_sha1.Sum(nil)) //nil 等同于 []byte("")
          }
          func main() {
              // 靜態(tài)資源處理
              http.Handle("/static/",
              http.StripPrefix("/static/",
              http.FileServer(http.Dir("./static"))))
              // 動態(tài)接口路由設置
              http.HandleFunc("/index", indexHandler)
              http.HandleFunc("/home", homeHandler)
              http.HandleFunc("/user", userHandler)
              http.HandleFunc("/upload", uploadHandler)
              http.HandleFunc("/download", downloadHandler)
              // 監(jiān)聽端口
              fmt.Println("上傳服務正在啟動, 監(jiān)聽端口:8080...")
              err :=http.ListenAndServe(":8080", nil)
              if err !=nil {
                  fmt.Printf("Failed to start server, err:%s", err.Error())
              }
          }

          tatic/upload.html

          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="utf-8">
          <title></title>
          </head>
          <body>
          <form action="/upload" method="POST" enctype="multipart/form-data">
          <input type="file" name="image" value="upload" />
          <input type="submit" value="上傳"/>
          </form>
          </body>
          </html>
          static/index.html
          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="utf-8">
          <title></title>
          </head>
          <body>
          <p>這是首頁的內(nèi)容</p>
          </body>
          </html>
          D:\work\src>go run main.go
          上傳服務正在啟動, 監(jiān)聽端口:8080...

          http://localhost:8080/download?filename=redis.png


          主站蜘蛛池模板: 精品三级AV无码一区| 色狠狠色噜噜Av天堂一区| 国产高清在线精品一区二区三区| 99精品国产高清一区二区三区| 精品午夜福利无人区乱码一区| 国产波霸爆乳一区二区| 国精产品一区一区三区MBA下载| 天堂资源中文最新版在线一区 | 在线精品日韩一区二区三区| 亚洲一区二区中文| 国产一区二区三区久久精品| 亚洲一区二区三区免费| 冲田杏梨高清无一区二区| 久久人妻无码一区二区| 亚洲AV无码一区二区三区牛牛| 无码人妻精品一区二区三18禁| 国产精品一区12p| 精品国产一区二区三区2021| 一区二区中文字幕在线观看| 无码av不卡一区二区三区| 国产女人乱人伦精品一区二区 | 日本香蕉一区二区三区| 国精产品一区一区三区MBA下载| 怡红院AV一区二区三区| 精品国产一区在线观看| 国产人妖视频一区在线观看| 精品一区二区AV天堂| 一区二区三区视频免费观看| 国产成人精品一区在线| 色妞AV永久一区二区国产AV| 亚洲AV无码一区二区三区系列 | 国产免费一区二区三区免费视频| 色综合视频一区二区三区| 精品乱子伦一区二区三区高清免费播放| 秋霞电影网一区二区三区| 亚洲日本一区二区一本一道| 日本不卡在线一区二区三区视频| 无码人妻精品一区二区三区久久| 国产精品一区在线麻豆| 狠狠综合久久av一区二区| 国产成人综合精品一区|