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 久久精品视频免费播放,国产成人精品日本亚洲直播一,国产三级精品在线

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          網站建設運用H5有什么好處

          網站建設運用H5有什么好處

          站建設市場競爭越來越激烈,領先的網站建設技術是立足的根本,建站企業只有與時俱進,不斷更新適應市場的技術才能免遭淘汰。既然H5是網站建設時代的產物,就要懂得運用它來提升網站的質量,適應用戶的需求。網站建設運用H5技術有什么好處呢?下面就來看看。

          一、頁面豐富。H5技術實現的網站也即是常說的響應式設計,改善了頁面多媒體元素的使用問題,之前建站頁面主張減少動畫、視頻等的使用,由于所占的網站資源空間多,導致頁面加載速度慢的情況,但如今使用H5建站,不僅可以大膽使用這些元素,且無需擔心瀏覽不順暢的問題,同時讓頁面顯得更加豐富,又能保證其整潔性。

          二、利于網站優化。一個網站如果不能很好的利用互聯網資源,那么建站就沒有其價值所在,其中搜索引擎這個大平臺就是資源利用的一個好渠道,由此網站必然少不了優化。H5技術所使用的代碼程序相對來說要簡潔得多,且運用多媒體的情況下,對搜索引擎的抓取也是非常友好的,因此網站優化起來更加輕松。

          三、提升用戶體驗。H5的出現,改善了網頁內容被插件束縛的局面,創造了豐富多彩的網站,滿足了用戶視覺上的審美要求,且能夠保證網站的加載速度,更重要的是當前的各種瀏覽器的推出,對于不同的用戶有不同的使用習慣,H5很好地兼容各種瀏覽器的,讓網站的呈現效果不會因設備的不同而改變,大大提高了用戶體驗。

          四、增加網站流量。由于H5技術實現了網站跨平臺的運用,尤其移動設備的多樣化,包括各種屏幕大小的手機,平板等等,毫無疑問,在移動互聯網的趨勢下,大半的用戶流量將來源于移動端的用戶,H5網站的建設,輕松拓展了用戶瀏覽渠道,給網站增加流量。

          本文由成都網站建設公司、成都網站設計制作公司、成都APP開發公司、成都響應式網站建設-新線加科技為您整理發布,希望能對你有所幫助!本文來自:http://www.scwbo.com/news/newsdetail101_403.html

          次NGINX在嘗試處理客戶端請求時遇到錯誤,它都會返回一個錯誤。每個錯誤都包含一個HTTP響應代碼和一個簡短描述。錯誤通常通過簡單的默認HTML頁面顯示給用戶。

          幸運的是,您可以配置NGINX以向您的站點或 Web 應用程序的用戶顯示自定義錯誤頁面。這可以使用 NGINX 的 error_page指令來實現,該指令用于定義將針對指定錯誤顯示的URI 。您還可以選擇使用它來修改發送給客戶端的響應標頭中的 HTTP 狀態代碼。

          在本指南中,我們將展示如何配置NGINX以使用自定義錯誤頁面。

          為所有 NGINX 錯誤創建一個自定義頁面

          您可以將NGINX配置為使用單個自定義錯誤頁面來處理它返回給客戶端的所有錯誤。首先創建您的錯誤頁面。這是一個示例,一個顯示消息的簡單 HTML 頁面:

          “Sorry, the page can't be loaded! Contact the site's administrator or support for assistance.” to a client.

          示例 HTML Nginx 自定義頁面代碼。

          <!DOCTYPE html><html><head><style type=text/css>* {
          	-webkit-box-sizing: border-box;
          	box-sizing: border-box;}body {
          	padding: 0;
          	margin: 0;}#notfound {
          	position: relative;
          	height: 100vh;}#notfound .notfound {
          	position: absolute;
          	left: 50%;
          	top: 50%;
          	-webkit-transform: translate(-50%, -50%);
          	-ms-transform: translate(-50%, -50%);
          	transform: translate(-50%, -50%);}.notfound {
          	max-width: 520px;
          	width: 100%;
          	line-height: 1.4;
          	text-align: center;}.notfound .notfound-error {
          	position: relative;
          	height: 200px;
          	margin: 0px auto 20px;
          	z-index: -1;}.notfound .notfound-error h1 {
          	font-family: 'Montserrat', sans-serif;
          	font-size: 200px;
          	font-weight: 300;
          	margin: 0px;
          	color: #211b19;
          	position: absolute;
          	left: 50%;
          	top: 50%;
          		-webkit-transform: translate(-50%, -50%);
          		-ms-transform: translate(-50%, -50%);
          		transform: translate(-50%, -50%);}@media only screen and (max-width: 767px) {
          	.notfound .notfound-error h1 {
          		font-size: 148px;
          	}}@media only screen and (max-width: 480px) {
          	.notfound .notfound-error {
          	height: 148px;
          	margin: 0px auto 10px;}.notfound .notfound-error h1 {
          	font-size: 120px;
          	font-weight: 200px;}.notfound .notfound-error h2 {
          	font-size: 30px;}.notfound a {
          	padding: 7px 15px;
          	font-size: 24px;}.h2 {
          	font-size: 148px;}}</style></head><body><div id="notfound">
          	<div class="notfound">
          		<h1>Sorry the page can't be loaded!</a></h1>
          		<div class="notfound-error">
          			<p>Contact the site's administrator or support for assistance.</p>
          		</div>
          	</div></div></body></html>

          使用適當的名稱保存文件,例如error-page.html并關閉它。

          接下來,將文件移動到您的文檔根目錄 ( /var/www/html/ )。如果該目錄不存在,您可以使用mkdir命令創建它,如下所示:

          $ sudo mkdir -p  /var/www/html/
          $ sudo cp error-page.html /var/www/html/

          然后使用error_page指令配置NGINX以使用自定義錯誤頁面。如圖所示,在/etc/nginx/snippets/下創建一個名為custom-error-page.conf的配置文件。

          $ sudo mkdir /etc/nginx/snippets/
          $ sudo vim /etc/nginx/snippets/custom-error-page.conf
          

          向其中添加以下行:

          error_page 404 403 500 503 /error-page.html;location=/error-page.html {
                  root /var/www/html;
                  internal;}

          每次NGINX遇到任何指定的 HTTP 錯誤 404、403、500 和 503 時,此配置都會導致內部重定向到URI / error-page.html。位置上下文告訴NGINX在哪里可以找到錯誤頁面。

          保存文件并關閉它。

          現在在http上下文中包含該文件,以便所有服務器塊都使用/etc/nginx/nginx.conf文件中的錯誤頁面:

          $ sudo vim /etc/nginx/nginx.conf

          包含目錄告訴NGINX將配置包含在指定.conf文件中:

          include snippets/custom-error-page.conf;

          或者,您可以包含特定服務器塊(通常稱為vhost)的文件,例如/etc/nginx/conf.d/mywebsite.conf。在服務器上下文中添加上述包含指令: {}

          保存您的NGINX配置文件并重新加載服務,如下所示:

          $ sudo systemctl reload nginx.service

          并從瀏覽器測試設置是否正常。

          為每個 NGINX 錯誤創建不同的自定義頁面

          您還可以為NGINX中的每個 HTTP 錯誤設置不同的自定義錯誤頁面。

          要在服務器上設置存儲庫,請運行以下命令:

          $ sudo git clone https://github.com/denysvitali/nginx-error-pages /srv/http/default
          $ sudo mkdir /etc/nginx/snippets/
          $ sudo ln -s /srv/http/default/snippets/error_pages.conf /etc/nginx/snippets/error_pages.conf
          $ sudo ln -s /srv/http/default/snippets/error_pages_content.conf /etc/nginx/snippets/error_pages_content.conf

          接下來,在您的http上下文或每個服務器塊/虛擬主機中添加以下配置:

          include snippets/error_pages.conf;

          保存您的 NGINX 配置文件并重新加載服務,如下所示:

          $ sudo systemctl reload nginx.service

          此外,如果配置按預期工作,請從瀏覽器測試。在這個示例中,我們測試了 404 錯誤頁面。

          這就是我們在本指南中為您提供的全部內容。NGINX 的error_page指令允許您在發生錯誤時將用戶重定向到定義的頁面或資源或 URL。它還可選地允許在對客戶端的響應中修改 HTTP 狀態代碼。

          家好,我是 polarisxu。

          前幾天我寫了一篇文章:Go項目實戰:一步步構建一個并發文件下載器,有小伙伴評論問,請求 https://studygolang.com/dl/golang/go1.16.5.src.tar.gz 為什么沒有返回 Accept-Ranges。在寫那篇文章時,我也試了,確實沒有返回,因此我以為它不支持。

          但有一個小伙伴很認真,他改用 GET 方法請求這個地址,結果卻有 Accept-Ranges,于是就很困惑,問我什么原因。經過一頓操作猛如虎,終于知道原因了。記錄下排查過程,供大家參考!(小伙伴的留言可以查看那篇文章)

          01 排查過程

          通過 curl 命令,分別用 GET 和 HEAD 方法請求這個地址,結果如下:

          $ curl -X GET --head https://studygolang.com/dl/golang/go1.16.5.src.tar.gz
          HTTP/1.1 303 See Other
          Server: nginx
          Date: Wed, 07 Jul 2021 09:09:35 GMT
          Content-Length: 0
          Connection: keep-alive
          Location: https://golang.google.cn/dl/go1.16.5.src.tar.gz
          X-Request-Id: 83ee595c-6270-4fb0-a2f1-98fdc4d315be
          
          $ curl --head https://studygolang.com/dl/golang/go1.16.5.src.tar.gz
          HTTP/1.1 200 OK
          Server: nginx
          Date: Wed, 07 Jul 2021 09:09:44 GMT
          Connection: keep-alive
          X-Request-Id: f2ba473d-5bee-44c3-a591-02c358551235
          

          雖然都沒有 Accept-Ranges,但有一個奇怪現象:一個狀態碼是 303,一個是 200。很顯然,303 是正確的,HEAD 為什么會是 200?

          我以為是 Nginx 對 HEAD 請求做了特殊處理,于是直接訪問 Go 服務的方式(不經過 Nginx 代理),結果一樣。

          于是,我用 Go 實現一個簡單的 Web 服務,Handler 里面也重定向。

          func main() {
           http.HandleFunc("/dl", func(w http.ResponseWriter, r *http.Request) {
            http.Redirect(w, r, "/", http.StatusSeeOther)
           })
           http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "Hello World")
           })
           http.ListenAndServe(":2022", nil)
          }
          

          用 curl 請求 http://localhost:2022/dl,GET 和 HEAD 都返回 303。于是我懷疑是不是 Echo 框架哪里的問題(studygolang 使用 Echo 框架構建的)。

          所以,我用 Echo 框架寫個 Web 服務測試:

          func main() {
           e := echo.New()
            
           e.GET("/dl", func(ctx echo.Context) error {
              return ctx.Redirect(http.StatusSeeOther, "/")
            })
            e.GET("/", func(ctx echo.Context) error {
              return ctx.String(http.StatusOK, "Hello World!")
            })
           
           e.Logger.Fatal(e.Start(":2022"))
          }
          

          同樣用 curl 請求 http://localhost:2022/dl,GET 返回 303,而 HEAD 報 405 Method Not Allowed,這符合預期。我們的路由設置只允許 GET 請求。但為什么 studygolang 沒有返回 405,因為它也限制只能 GET 請求。

          于是我對隨便一個地址發起 HEAD 請求,發現都返回 200,可見 HTTP 錯誤被“吞掉”了。查找 studygolang 的中間件,發現了這個:

          func HTTPError() echo.MiddlewareFunc {
           return func(next echo.HandlerFunc) echo.HandlerFunc {
            return func(ctx echo.Context) error {
             if err := next(ctx); err != nil {
          
              if !ctx.Response().Committed {
               if he, ok := err.(*echo.HTTPError); ok {
                switch he.Code {
                case http.StatusNotFound:
                 if util.IsAjax(ctx) {
                  return ctx.String(http.StatusOK, `{"ok":0,"error":"接口不存在"}`)
                 }
                 return Render(ctx, "404.html", nil)
                case http.StatusForbidden:
                 if util.IsAjax(ctx) {
                  return ctx.String(http.StatusOK, `{"ok":0,"error":"沒有權限訪問"}`)
                 }
                 return Render(ctx, "403.html", map[string]interface{}{"msg": he.Message})
                case http.StatusInternalServerError:
                 if util.IsAjax(ctx) {
                  return ctx.String(http.StatusOK, `{"ok":0,"error":"接口服務器錯誤"}`)
                 }
                 return Render(ctx, "500.html", nil)
               }
              }
             }
             return nil
            }
           }
          }
          

          這里對 404、403、500 錯誤都做了處理,但其他 HTTP 錯誤直接忽略了,導致最后返回了 200 OK。只需要在上面 switch 語句加一個 default 分支,同時把 err 原樣 return,采用系統默認處理方式:

          default:
           return err
          

          這樣 405 Method Not Allowed 會正常返回。

          同時,為了解決 HEAD 能用來判斷下載行為,針對下載路由,我加上了允許 HEAD 請求,這樣就解決了小伙伴們的困惑。

          02 curl 和 Go 代碼行為異同

          不知道大家發現沒有,通過 curl 請求 https://studygolang.com/dl/golang/go1.16.5.src.tar.gz 和 Go 代碼請求,結果是不一樣的:

          $ curl -X GET --head https://studygolang.com/dl/golang/go1.16.5.src.tar.gz
          HTTP/1.1 303 See Other
          Server: nginx
          Date: Thu, 08 Jul 2021 02:05:10 GMT
          Content-Length: 0
          Connection: keep-alive
          Location: https://golang.google.cn/dl/go1.16.5.src.tar.gz
          X-Request-Id: 14d741ca-65c1-4b05-90b8-bef5c8b5a0a3
          

          返回的是 303 重定向,自然沒有 Accept-Ranges 頭。

          但改用如下 Go 代碼:

          resp, err := http.Get("https://studygolang.com/dl/golang/go1.16.5.src.tar.gz")
          if err != nil {
            fmt.Println("get err", err)
            return
          }
          
          fmt.Println(resp)
          fmt.Println("ranges", resp.Header.Get("Accept-Ranges"))
          

          返回的是 200,且有 Accept-Ranges 頭。可以猜測,應該是 Go 根據重定向遞歸請求重定向后的地址。可以查看源碼確認下。

          通過這個可以看到:https://docs.studygolang.com/src/net/http/client.go?s=20406:20458#L574,核心代碼如下(比較容易看懂):

          // 循環處理所有需要處理的 url(包括重定向后的)
          for {
            // For all but the first request, create the next
            // request hop and replace req.
            if len(reqs) > 0 {
                // 如果是重定向,請求重定向地址
             loc := resp.Header.Get("Location")
             if loc == "" {
              resp.closeBody()
              return nil, uerr(fmt.Errorf("%d response missing Location header", resp.StatusCode))
             }
             u, err := req.URL.Parse(loc)
             if err != nil {
              resp.closeBody()
              return nil, uerr(fmt.Errorf("failed to parse Location header %q: %v", loc, err))
             }
             host := ""
             if req.Host != "" && req.Host != req.URL.Host {
              // If the caller specified a custom Host header and the
              // redirect location is relative, preserve the Host header
              // through the redirect. See issue #22233.
              if u, _ := url.Parse(loc); u != nil && !u.IsAbs() {
               host = req.Host
              }
             }
             ireq := reqs[0]
             req = &Request{
              Method:   redirectMethod,
              Response: resp,
              URL:      u,
              Header:   make(Header),
              Host:     host,
              Cancel:   ireq.Cancel,
              ctx:      ireq.ctx,
             }
             if includeBody && ireq.GetBody != nil {
              req.Body, err = ireq.GetBody()
              if err != nil {
               resp.closeBody()
               return nil, uerr(err)
              }
              req.ContentLength = ireq.ContentLength
             }
          
             // Copy original headers before setting the Referer,
             // in case the user set Referer on their first request.
             // If they really want to override, they can do it in
             // their CheckRedirect func.
             copyHeaders(req)
          
             // Add the Referer header from the most recent
             // request URL to the new one, if it's not https->http:
             if ref := refererForURL(reqs[len(reqs)-1].URL, req.URL); ref != "" {
              req.Header.Set("Referer", ref)
             }
             err = c.checkRedirect(req, reqs)
          
             // Sentinel error to let users select the
             // previous response, without closing its
             // body. See Issue 10069.
             if err == ErrUseLastResponse {
              return resp, nil
             }
          
             // Close the previous response's body. But
             // read at least some of the body so if it's
             // small the underlying TCP connection will be
             // re-used. No need to check for errors: if it
             // fails, the Transport won't reuse it anyway.
             const maxBodySlurpSize = 2 << 10
             if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
              io.CopyN(io.Discard, resp.Body, maxBodySlurpSize)
             }
             resp.Body.Close()
          
             if err != nil {
              // Special case for Go 1 compatibility: return both the response
              // and an error if the CheckRedirect function failed.
              // See https://golang.org/issue/3795
              // The resp.Body has already been closed.
              ue := uerr(err)
              ue.(*url.Error).URL = loc
              return resp, ue
             }
            }
          
            reqs = append(reqs, req)
            var err error
            var didTimeout func() bool
            if resp, didTimeout, err = c.send(req, deadline); err != nil {
             // c.send() always closes req.Body
             reqBodyClosed = true
             if !deadline.IsZero() && didTimeout() {
              err = &httpError{
               // TODO: early in cycle: s/Client.Timeout exceeded/timeout or context cancellation/
               err:     err.Error() + " (Client.Timeout exceeded while awaiting headers)",
               timeout: true,
              }
             }
             return nil, uerr(err)
            }
          
             // 確認重定向行為
            var shouldRedirect bool
            redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
            if !shouldRedirect {
             return resp, nil
            }
          
            req.closeBody()
           }
          

          可以進一步看 redirectBehavior 函數 https://docs.studygolang.com/src/net/http/client.go?s=20406:20458#L497:

          func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect, includeBody bool) {
           switch resp.StatusCode {
           case 301, 302, 303:
            redirectMethod = reqMethod
            shouldRedirect = true
            includeBody = false
          
            // RFC 2616 allowed automatic redirection only with GET and
            // HEAD requests. RFC 7231 lifts this restriction, but we still
            // restrict other methods to GET to maintain compatibility.
            // See Issue 18570.
            if reqMethod != "GET" && reqMethod != "HEAD" {
             redirectMethod = "GET"
            }
           case 307, 308:
            redirectMethod = reqMethod
            shouldRedirect = true
            includeBody = true
          
            // Treat 307 and 308 specially, since they're new in
            // Go 1.8, and they also require re-sending the request body.
            if resp.Header.Get("Location") == "" {
             // 308s have been observed in the wild being served
             // without Location headers. Since Go 1.7 and earlier
             // didn't follow these codes, just stop here instead
             // of returning an error.
             // See Issue 17773.
             shouldRedirect = false
             break
            }
            if ireq.GetBody == nil && ireq.outgoingLength() != 0 {
             // We had a request body, and 307/308 require
             // re-sending it, but GetBody is not defined. So just
             // return this response to the user instead of an
             // error, like we did in Go 1.7 and earlier.
             shouldRedirect = false
            }
           }
           return redirectMethod, shouldRedirect, includeBody
          }
          

          很清晰了吧。

          03 總結

          很開心,還是有讀者很認真的在看我的文章,在跟著動手實踐,還對其中的點提出質疑。希望通過這篇文章,大家能夠對 HTTP 協議有更深的認識,同時體會問題排查的思路。

          有其他問題,也歡迎留言交流!


          主站蜘蛛池模板: 一区二区在线观看视频| 亚洲av午夜福利精品一区| 国产美女露脸口爆吞精一区二区| 视频一区二区三区免费观看| 老熟女高潮一区二区三区| 精品国产免费一区二区三区| 久久人妻无码一区二区| 无码人妻精品一区二区三18禁| 好湿好大硬得深一点动态图91精品福利一区二区| 国产91大片精品一区在线观看| 日本一区免费电影| 亚洲AV无码第一区二区三区| 一区二区三区91| 国产aⅴ一区二区三区| 加勒比无码一区二区三区| 亚洲一区精品中文字幕| 中文字幕一区精品| 久久久99精品一区二区| 国产一区二区三区无码免费| 中文精品一区二区三区四区| 国产精品一区二区久久| 3d动漫精品啪啪一区二区中文| 亚洲国产精品无码久久一区二区| 无码日韩人妻AV一区二区三区| 国产麻豆剧果冻传媒一区| 日韩精品久久一区二区三区 | 亚洲日本乱码一区二区在线二产线| 日韩一区二区精品观看| 无码人妻精品一区二区蜜桃AV| 丰满人妻一区二区三区视频| 久久人做人爽一区二区三区| 久久无码人妻一区二区三区| 无码人妻久久一区二区三区| 99精品国产一区二区三区不卡| 日韩AV无码久久一区二区| 中文无码一区二区不卡αv| 韩国一区二区三区视频| 日本精品一区二区久久久| 国产精品亚洲综合一区| 夜色福利一区二区三区| 中文字幕日韩一区二区不卡|