{"id":1767,"date":"2020-10-13T04:01:13","date_gmt":"2020-10-12T20:01:13","guid":{"rendered":"https:\/\/www.develop-note.com\/blog\/?p=1767"},"modified":"2022-02-16T21:49:22","modified_gmt":"2022-02-16T13:49:22","slug":"iris-middleware-2021ironman","status":"publish","type":"post","link":"https:\/\/www.develop-note.com\/blog\/2020\/10\/13\/iris-middleware-2021ironman\/","title":{"rendered":"Iris \u9019\u500b\u5728 go \u8a9e\u8a00\u4e0a\u5730\u8868\u6700\u5feb\u7684\u7db2\u9801\u6846\u67b6-iris\u7684middleware"},"content":{"rendered":"<h1>middleware<\/h1>\n<p>\u5728\u4e0a\u7bc7\u6587\u7ae0\u4ecb\u7d39routing\u6642\u6709\u63d0\u5230<code>Party<\/code>\u6642\u6709\u50b3\u5165\u4e00\u500b<code>handler<\/code>\u4e0d\u77e5\u9053\u8b80\u8005\u5011\u6709\u6c92\u6709\u6ce8\u610f\u5230\uff0c\u6240\u4ee5\u4eca\u5929\u4f86\u4ecb\u7d39\u90a3\u500b<code>middleware<\/code>\u3002<\/p>\n<p><!--more--><\/p>\n<h2>middleware<\/h2>\n<p>\u5176\u5be6middleware\u5728\u5f88\u591a\u7db2\u9801\u7a0b\u5f0f\u88e1\u90fd\u6709\uff0c\u4e0d\u904e\u5728\u4ecb\u7d39iris\u7684middleware\u4e4b\u524d\u9084\u662f\u4ecb\u7d39\u4e00\u4e0b\u4ec0\u9ebc\u662fmiddleware\uff0c\u6240\u4ee5\u63a5\u4e0b\u4f86\u7684\u5167\u5bb9\u5c31\u5148\u4ecb\u7d39\u4ec0\u9ebc\u662fmiddleware\uff0c\u518d\u4f86\u518d\u958b\u59cb\u4ecb\u7d39\u5728iris\u600e\u9ebc\u64b0\u5bebmiddleware\u3002<\/p>\n<h3>\u751a\u9ebc\u662fmiddleware<\/h3>\n<p>\u4ec0\u9ebc\u662fmiddleware\u5462\uff0c\u9019\u88e1\u9084\u662f\u5148\u770b\u770b<a href=\"https:\/\/en.m.wikipedia.org\/wiki\/Middleware\" title=\"middleware wiki\" rel=\"nofollow noopener\" target=\"_blank\">middleware wiki<\/a>\u7684\u89e3\u91cb\u5427\uff0c\u5c0d\u65bc\u7b46\u8005\u7684\u89e3\u91cb\u8207\u5176\u985e\u4f3c\uff0c\u7c21\u55ae\u4f86\u8aaa\u660e\u5c31\u662f\u5728\u7db2\u9801\u7a0b\u5f0f\u7684\u751f\u547d\u9031\u671f\u4e2d\u5207\u5165\u4e00\u6bb5\u670d\u52d9\uff0c\u85c9\u6b64\u4f86\u8655\u7406\u6240\u6709\u7684\u8acb\u6c42\uff0c\u63a5\u4e0b\u4f86\u5c31\u958b\u59cb\u8ddf\u5927\u5bb6\u4ecb\u7d39\u5982\u4f55\u64b0\u5bebiris\u7684middleware\u3002<\/p>\n<h3>irir\u5982\u4f55\u64b0\u5bebmiddleware<\/h3>\n<p>\u9019\u908a\u5229\u7528<a href=\"https:\/\/www.iris-go.com\/docs#\/?id=custom-middleware\" title=\"custom-middleware\" rel=\"nofollow noopener\" target=\"_blank\">iris-go custom-middleware<\/a>\u4f86\u8aaa\u660e\u5982\u4f55\u64b0\u5bebmiddleware\uff0c\u8acb\u5927\u5bb6\u5148\u770b\u770b\u4ee5\u4e0b\u4f8b\u5b50<\/p>\n<pre><code class=\"language-go\">func Logger() iris.Handler {\n    return func(ctx iris.Context) {\n        t := time.Now()\n\n        \/\/ Set a shared variable between handlers\n        ctx.Values().Set(&quot;framework&quot;, &quot;iris&quot;)\n\n        \/\/ before request\n\n        ctx.Next()\n\n        \/\/ after request\n        latency := time.Since(t)\n        log.Print(latency)\n\n        \/\/ access the status we are sending\n        status := ctx.GetStatusCode()\n        log.Println(status)\n    }\n}\n\nfunc main() {\n    app := iris.New()\n    app.Use(Logger())\n\n    app.Get(&quot;\/test&quot;, func(ctx iris.Context) {\n        \/\/ retrieve a value set by the middleware.\n        framework := ctx.Values().GetString(&quot;framework&quot;)\n\n        \/\/ it would print: &quot;iris&quot;\n        log.Println(framework)\n    })\n\n    app.Listen(&quot;:8080&quot;)\n}<\/code><\/pre>\n<p>\u7c21\u55ae\u8b1b\u5982\u4f55\u64b0\u5beb\u4e00\u500b\u81ea\u8a02\u7fa9\u7684middleware\u5c31\u662f\u8fd4\u9084\u4e00\u500b<code>handdler<\/code>\uff0c\u64b0\u5bebmiddleware\u7684\u8981\u9ede\u4e3b\u8981\u662f\u5340\u5206\u8655\u7406\u8acb\u6c42\u4e4b\u524d\u8ddf\u8655\u7406\u5b8c\u8acb\u6c42\u7684\u90e8\u5206\uff0c\u770b\u5230\u4e0a\u9762\u7684\u4f8b\u5b50\u5c31\u77e5\u9053\u5176\u4e2d\u7684\u5340\u9694\u662f\u4e00\u500b<code>ctx.Next()<\/code>\uff0c\u547c\u53eb\u9019\u500b\u65b9\u6cd5\u4e4b\u524d\u662f\u8655\u7406\u8acb\u6c42\u4e4b\u524d\uff0c\u547c\u53eb\u5b8c\u5c31\u662f\u8655\u7406\u8acb\u6c42\u4e4b\u5f8c\u3002<br \/>\n\u7136\u800c\u5982\u4f55\u5206\u4eab\u8b8a\u6578\u5728<code>handler<\/code>\u4e4b\u9593\u5462\uff0c\u5c31\u662f\u900f\u904e<code>ctx.Values().Set(key string, value object)<\/code>\u8207<code>ctx.Values().GetString(key string) string<\/code>\u4e4b\u985e\u7684\u65b9\u6cd5\u3002<\/p>\n<h3>\u5982\u4f55\u4f7f\u7528middleware<\/h3>\n<p>\u4e0a\u9762\u4f8b\u5b50\u8aaa\u660e\u5982\u4f55\u64b0\u5bebmiddleware\uff0c\u4e5f\u63d0\u5230\u4e00\u500b\u5982\u4f55\u4f7f\u7528middleware\u7684\u65b9\u6cd5\uff0c\u7c21\u55ae\u4f86\u8aaa\u5c31\u662f\u900f\u904eapp.Use(h handler)\u4f86\u4f7f\u7528middleware\uff0c\u4e0d\u904e\u4f7f\u7528\u7684\u65b9\u5f0f\u4e0d\u53ea\u9019\u6a23\uff0c\u9084\u6709\u4e0b\u5217\u5e7e\u7a2e\u65b9\u6cd5<\/p>\n<ul>\n<li>Party.UseError<\/li>\n<li>Party.Use<\/li>\n<li>Party.UseOnce<\/li>\n<li>Application.UseGlobal<\/li>\n<li>Party.Done<\/li>\n<li>Application.DoneGlobal<\/li>\n<li>Party.UseRouter<\/li>\n<li>Application.WrapRouter<\/li>\n<\/ul>\n<p>\u81f3\u65bc\u5176\u4e2d\u7684\u5dee\u5225\u53ef\u4ee5\u770b\u770b<a href=\"https:\/\/docs.iris-go.com\/iris\/routing\/middleware\" title=\"middleware \" rel=\"nofollow noopener\" target=\"_blank\">iris-go middleware<\/a>\u7684\u5167\u5bb9\uff0c\u9996\u5148\u5148\u770b\u770b\u4ed6\u7684\u4f8b\u5b50<\/p>\n<pre><code class=\"language-go\">package main\n\nimport (\n    &quot;net\/http&quot;\n\n    &quot;github.com\/kataras\/iris\/v12&quot;\n)\n\nfunc main() {\n    app := iris.New()\n\n    app.WrapRouter(routerWrapper)\n    app.UseRouter(routerMiddleware)\n    app.UseGlobal(globalMiddleware)\n    app.Use(useMiddleware)\n    app.UseError(errorMiddleware)\n    \/\/ app.Done(done)\n    \/\/ app.DoneGlobal(doneGlobal)\n\n    \/\/ Adding a OnErrorCode(iris.StatusNotFound) causes `.UseGlobal`\n    \/\/ to be fired on 404 pages without this,\n    \/\/ only `UseError` will be called, and thus should\n    \/\/ be used for error pages.\n    app.OnErrorCode(iris.StatusNotFound, notFoundHandler)\n\n    app.Get(&quot;\/&quot;, mainHandler)\n\n    app.Listen(&quot;:8080&quot;)\n}\n\nfunc mainHandler(ctx iris.Context) {\n    ctx.WriteString(&quot;Main Handler&quot;)\n}\n\nfunc notFoundHandler(ctx iris.Context) {\n    ctx.WriteString(&quot;404 Error Handler&quot;)\n}<\/code><\/pre>\n<p>\u4e0a\u9762\u662f\u4e3b\u7a0b\u5f0f\u4ee5\u53ca\u7d81\u5b9amiddleware\u7684\u8cc7\u8a0a\uff0c\u63a5\u4e0b\u4f86\u770b\u770b\u671fmiddleware\u7684\u5167\u5bb9<\/p>\n<pre><code class=\"language-go\">func routerWrapper(w http.ResponseWriter, r *http.Request,\n    router http.HandlerFunc) {\n\n    if r.URL.Path == &quot;\/&quot; {\n        w.Write([]byte(&quot;#1 .WrapRouter\\n&quot;))\n        \/* Note for new Gophers:\n            If we Write anything here on an error resource in the raw\n            `net\/http` wrapper like this one, then the response writer will\n            automatically send a `200` OK status code (when we first write).\n            Any error handler executed after this will not fire as expected.\n            Also, when `w.WriteHeader` is called you can NOT change the\n            status code later on.\n\n            In Iris Handlers, if you write before the status code has been\n            set, then it will also automatically send the 200 OK status\n            code which then cannot be changed later. However, if we call\n            `ctx.StatusCode` inside an Iris Handler without writing any\n            content, then we can change the status code later on. When you\n            need to change that behaviour, you must start the handler with\n            a `ctx.Record` call.\n        *\/\n    }\n\n    \/\/ Continue by executing the Iris Router and let it do its job.\n    router(w, r)\n}\n\nfunc routerMiddleware(ctx iris.Context) {\n    if ctx.Path() == &quot;\/&quot; {\n        ctx.WriteString(&quot;#2 .UseRouter\\n&quot;)\n    \/\/ The same caveat described in routerWrapper applies here as well.\n    }\n\n    ctx.Next()\n}\n\nfunc globalMiddleware(ctx iris.Context) {\n    ctx.WriteString(&quot;#3 .UseGlobal\\n&quot;)\n    ctx.Next()\n}\n\nfunc useMiddleware(ctx iris.Context) {\n    ctx.WriteString(&quot;#4 .Use\\n&quot;)\n    ctx.Next()\n}\n\nfunc errorMiddleware(ctx iris.Context) {\n    ctx.WriteString(&quot;#3 .UseError\\n&quot;)\n    ctx.Next()\n}<\/code><\/pre>\n<p>\u9019\u88e1\u7684middleware\u90fd\u53ea\u662f\u5beblog\u800c\u5df2\uff0c\u7136\u5f8c\u57f7\u884c\u9019\u500b\u7a0b\u5f0f\u6703\u6709\u751a\u9ebc\u7d50\u679c\u5462\uff0c\u8acb\u5927\u5bb6\u770b\u770b\u4ee5\u4e0b\u7684\u5167\u5bb9<\/p>\n<pre><code class=\"language-bash\">#1 .WrapRouter\n#2 .UseRouter\n#3 .UseGlobal\n#4 .Use\nMain Handler<\/code><\/pre>\n<p>\u7531\u4e0a\u9762\u4f8b\u5b50\u53ef\u4ee5\u77e5\u9053\uff0c\u8a3b\u518amiddleware\u7684\u57f7\u884c\u9806\u5e8f\u662f\u5982\u4e0a\u9762\u986f\u793a\u7684\u9806\u5e8f<code>WrapRouter<\/code>\u6700\u5148\u88ab\u57f7\u884c\u3001<code>Use<\/code>\u6700\u5f8c\uff0c\u63a5\u4e0b\u4f86\u624d\u57f7\u884c\u7d81\u5b9a\u7684<code>handler<\/code>\uff0c\u9664\u6b64\u4e4b\u5916\u5982\u679c\u89f8\u767c404\u6703\u6709\u4e0b\u5217\u7684\u8f38\u51fa<\/p>\n<pre><code class=\"language-bash\">#3 .UseGlobal\n#3 .UseError\n404 Error Handler<\/code><\/pre>\n<p>\u4e0d\u904e\u9019\u88e1\u6709\u4e00\u500b\u90e8\u5206\u9700\u8981\u6ce8\u610f\u7684\uff0c\u5c31\u662f\u5982\u679c<code>OnErrorCode<\/code>\u6c92\u6709\u7d81\u5b9a\u5230\u7684\u72c0\u614b\u88ab\u89f8\u767c\uff0c<code>UseGlobal<\/code>\u4e5f\u4e0d\u6703\u88ab\u89f8\u767c\uff0c\u4f8b\u5982\u89f8\u767c\u7684\u4e0d\u662f404\u800c\u662f400\u5247\u6703\u8f38\u51fa\u7684log\u5982\u4e0b<\/p>\n<pre><code class=\"language-bash\">#3 .UseError\nNot Found<\/code><\/pre>\n<h3>\u4fee\u6539middleware<\/h3>\n<p>\u6700\u5f8c\u8ddf\u5927\u5bb6\u8aaa\u660e\u5982\u4f55\u4fee\u6539\u539f\u4f86\u7684middleware\uff0c\u7c21\u55ae\u8aaa\u5c31\u662f\u50cf\u63a5\u6c34\u7ba1\u4e00\u6a23\uff0c\u518d\u63a5\u539f\u4f86\u7684middleware\u4e4b\u524d\u5148\u63a5\u53e6\u5916\u4e00\u500bmiddleware\u53bb\u5224\u65b7\u5f8c\u5373\u53ef\uff0c\u5927\u5bb6\u53ef\u4ee5\u770b\u770b\u4e0b\u5217\u4f8b\u5b50<\/p>\n<pre><code class=\"language-go\">package main\n\nimport (\n    &quot;github.com\/kataras\/iris\/v12&quot;\n    &quot;github.com\/kataras\/iris\/v12\/middleware\/basicauth&quot;\n)\n\nfunc main() {\n    users := map[string]string{&quot;username&quot;:&quot;password&quot;}\n    auth := basicauth.New(basicauth.Default(users))\n\n    app.UseRouter(skipStaticSubdomain(auth)) \/\/ &lt;--\n\n    \/\/ [...]\n    app.Listen(&quot;:80&quot;)\n}\n\nfunc skipStaticSubdomain(handler iris.Handler) iris.Handler {\n    return func(ctx iris.Context) {\n        if ctx.Subdomain() == &quot;static.&quot; {\n            \/\/ continue to the next or main handler and exit.\n            ctx.Next()\n            return\n        }\n\n        handler(ctx)   \n    }\n}<\/code><\/pre>\n<p>\u9664\u4e86\u4e0a\u8ff0\u7684\u4f8b\u5b50\u4e4b\u5916\uff0c\u53e6\u5916\u53ef\u4ee5\u628a<code>condition<\/code>\u8ddf<code>handler<\/code>\u5206\u958b\u4f86\u5beb\uff0c\u900f\u904e<code>iris.NewConditionalHandler(filter Filter, handlers ...Handler) Handler<\/code>\u4f86\u6539\u5bebmiddleware\uff0c\u8a73\u898b\u4e0b\u5217\u4f8b\u5b50<\/p>\n<pre><code class=\"language-go\">app.UseRouter(iris.NewConditionalHandler(isNotStaticSubdomain, auth))\n\nfunc isNotStaticSubdomain(ctx iris.Context) bool {\n    return ctx.Subdomain() != &quot;static.&quot;\n}<\/code><\/pre>\n<h2>\u7d50\u8ad6<\/h2>\n<p>\u672c\u7bc7\u4ecb\u7d39\u4ec0\u9ebc\u662fmiddleware\uff0c\u4e26\u4e14\u4ecb\u7d39\u5982\u4f55\u5728iris\u64b0\u5bebmiddleware\uff0c\u5e0c\u671b\u5927\u5bb6\u5c0d\u65bciris\u7684middleware\u6709\u521d\u6b65\u7684\u6982\u5ff5\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>middleware \u5728\u4e0a\u7bc7\u6587\u7ae0\u4ecb\u7d39routing\u6642\u6709\u63d0\u5230Party\u6642\u6709\u50b3\u5165\u4e00\u500bhandler\u4e0d\u77e5\u9053\u8b80\u8005\u5011\u6709\u6c92 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.develop-note.com\/blog\/2020\/10\/13\/iris-middleware-2021ironman\/\" class=\"more-link\">\u95b1\u8b80\u5168\u6587<span class=\"screen-reader-text\">\u3008Iris \u9019\u500b\u5728 go \u8a9e\u8a00\u4e0a\u5730\u8868\u6700\u5feb\u7684\u7db2\u9801\u6846\u67b6-iris\u7684middleware\u3009<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[2],"tags":[158,81,84],"class_list":["post-1767","post","type-post","status-publish","format-standard","hentry","category-develop","tag-2020ironman","tag-go","tag-iris"],"_links":{"self":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/1767","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/comments?post=1767"}],"version-history":[{"count":13,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/1767\/revisions"}],"predecessor-version":[{"id":2950,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/posts\/1767\/revisions\/2950"}],"wp:attachment":[{"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/media?parent=1767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/categories?post=1767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.develop-note.com\/blog\/wp-json\/wp\/v2\/tags?post=1767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}