<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### session_start()初始化工作 - 讀取名為PHPSESSID的cookie值,這個值內容保存這session對應存儲的文件名,假設為abc123(由系統生成) - 若PHPSESSID存在,創建$_SESSION變量,讀取session文件(如SESS_abc123),讀取到的內容填充到$_SESSION變量中;若PHPSESSID不存在,創建$_SESSION和session文件(SESS_abc123),將abc123作為名喂PHPSESSID的cookie值返回給游覽器 - 由此可見,如果需要解決跨域問題,第一需要共享session文件,第二客戶端不能丟失sessionID ### session_id($id string) 返回當前會話ID,如果指定參數$id,則需要在session_start()之前調用,返回設置為$id的會話 ### 垃圾回收機制 session回收發生在session_start(),但不是每次都會執行回收,由session.gc_probability 和 session.gc_divisor兩個選項決定,計算如下: 系統會根據session.gc_probability/session.gc_divisor 公式計算概率,例如選項 session.gc_probability = 1,選項 session.gc_divisor = 100,這樣概率就變成了 1/100,也就是 session_start()函數被調用 100 次才會啟動一次 “ 垃圾回收程序 ” 。所以對會話頁面訪問越頻繁,啟動的概率就越來越小。一般的建議為 調用1000-5000次才會啟動一次: 1/(1000~5000)。 ### 登錄問題 一般登錄時候不會設置cookie過期時間,當游覽器退出時,cookie失效,用戶需要再次登錄;若設置了記住密碼,實際上是設置了cookie的過期時間,當游覽器退出時,只要cookie沒過期,就不需要再次登錄(前提是在退出游覽器時,用戶不能點擊退出登錄) ### GO實現session ```go package session import ( "encoding/json" "io/ioutil" "log" "math/rand" "net/http" "os" "sync" "time" ) const ( SESS_PREFIX string = "sess_" COOKIE_NAME string = "PHPSESSID" GC_PROBABILITY int = 1 GC_DIVISOR int = 100 SAVE_PATH string = "sess_files/" MAX_LIFE_TIME int64 = 86400 ) type Session struct { Req http.Request Writer http.ResponseWriter // 請求 Sfile string // session文件名 Sdata map[string]string // session值 Lock sync.RWMutex IsStart bool } func (s *Session) start() { defer s.Lock.Unlock() s.Lock.Lock() if s.IsStart { return } cookie, err := s.Req.Cookie(COOKIE_NAME) if err != nil { log.Fatal(err) } // 設置為啟動 s.IsStart = true // 首次訪問,生成名為PHPSESSID的cookie到客戶端 if !cookie { s.Sfile = SESS_PREFIX + GetRandomString(10) cookie = http.Cookie{Name: COOKIE_NAME, Value: s.SFile, Path: "/", MaxAge: "86400"} http.SetCookie(http.Writer, &cookie) return } else { s.Sfile = SESS_PREFIX + cookie.Value } // 讀取session值,并設置值 file, err := os.Open(s.Sfile) if err != nil { log.Fatal(err) } buf := make([]byte, 0) _, err := file.Read(buf) if err != nil { log.Fatal(err) } s.Sdata = make(map[string]string) json.Unmarshal(buf, s.Sdata) // 回收機制 rand.Seed(time.Now().Unix()) base := rand.Intn(GC_DIVISOR) if GC_PROBABILITY <= base { overtimeFiles, err := ioutil.ReadDir(SAVE_PATH) if err != nil { log.Fatal(err) } for _, fi := range overtimeFiles { modTime := fi.ModTime().Unix() if modTime-time.Now().Unix() > MAX_LIFE_TIME { os.Remove(SAVE_PATH + string(os.PathSeparator) + fi.Name()) } } } } func (s *Session) Set(key string, value string) { if !s.IsStart { log.Fatal("session is not start") } if s.Sdata == nil { s.Sdata = make(map[string]string) } s.Sdata[key] = value } func (s *Session) Get(key string) string { if !s.IsStart { log.Fatal("session is not start") } if v, ok := s.Sdata[key]; ok { return string(v) } else { return "" } } func (s *Session) Save() { if !s.IsStart { log.Fatal("session is not start") } str, err := json.Marshal(s.Sdata) if err != nil { log.Fatal(err) } file, err := os.Open(s.Sfile) if err != nil { log.Fatal(err) } n, err := file.Write([]byte(str)) if err != nil || n != len(str) { log.Fatal("save session failed") } } // 隨機字符串 func GetRandomString(l int) string { str := "0123456789abcdefghijklmnopqrstuvwxyz" bytes := []byte(str) result := []byte{} r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < l; i++ { result = append(result, bytes[r.Intn(len(bytes))]) } return string(result) } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看