2018/1/3
第十五天:從 Rails 認識 HTTP 協定( 2018 iT邦幫忙鐵人賽-只要有心,人人都可以作卡米狗 )
markdown
昨天我們學會了怎麼新增 Route 跟 Controller,並且知道怎麼控制要回應什麼內容給瀏覽器。
今天要使用這兩天學會的東西,我們要來看看瀏覽器到底傳了什麼給 Rails,以及 Rails 傳回什麼給瀏覽器。
# 做一組新的 Route 跟 Controller
我們在 `app/controllers/kamigo_controller.rb` 新增一個 `request_headers` 方法,嘗試把 `request` 中的 `headers` 傳回給瀏覽器。
```
class KamigoController < ApplicationController
def eat
render plain: "吃土啦"
end
def request_headers
render plain: request.headers
end
end
```
然後在 `config/routes.rb` 加入一行 `get '/kamigo/request_headers', to: 'kamigo#request_headers'`。
```
Rails.application.routes.draw do
get '/kamigo/eat', to: 'kamigo#eat'
get '/kamigo/request_headers', to: 'kamigo#request_headers'
end
```
開啟網頁伺服器,並且用瀏覽器打開網頁:[http://localhost:3000/kamigo/request_headers](http://localhost:3000/kamigo/request_headers)。
你會看到:
```
#
```
表示 `request.headers` 是一個 [ActionDispatch::Http::Headers](http://api.rubyonrails.org/classes/ActionDispatch/Http/Headers.html) 物件,但是其實我們想知道的是他包含的內容是什麼,而不是他是什麼類別的物件。
# 從 Rails 觀察 request.headers
所以我們需要改一下程式:
```
class KamigoController < ApplicationController
def eat
render plain: "吃土啦"
end
def request_headers
render plain: request.headers.to_h
end
end
```
加一個 `to_h` ,試著把物件轉成雜湊陣列看看。
```
{"rack.version"=>[1, 3],...
下略 180 萬字
```
結果是成功了,但是瀏覽器印出了 180 萬個字。
我們先試著忽略內容的部分,看一下他的關鍵字有哪些。
```
class KamigoController < ApplicationController
def eat
render plain: "吃土啦"
end
def request_headers
render plain: request.headers.to_h.keys
end
end
```
再加一個 `keys` ,試著把雜湊陣列轉成只包含關鍵字的陣列看看。
```
["rack.version", "rack.errors", "rack.multithread", "rack.multiprocess", "rack.run_once", "SCRIPT_NAME", "QUERY_STRING", "SERVER_PROTOCOL", "SERVER_SOFTWARE", "GATEWAY_INTERFACE", "REQUEST_METHOD", "REQUEST_PATH", "REQUEST_URI", "HTTP_VERSION", "HTTP_HOST", "HTTP_CONNECTION", "HTTP_CACHE_CONTROL", "HTTP_USER_AGENT", "HTTP_UPGRADE_INSECURE_REQUESTS", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_COOKIE", "HTTP_ALEXATOOLBAR_ALX_NS_PH", "HTTP_IF_NONE_MATCH", "SERVER_NAME", "SERVER_PORT", "PATH_INFO", "REMOTE_ADDR", "puma.socket", "rack.hijack?", "rack.hijack", "rack.input", "rack.url_scheme", "rack.after_reply", "puma.config", "action_dispatch.parameter_filter", "action_dispatch.redirect_filter", "action_dispatch.secret_token", "action_dispatch.secret_key_base", "action_dispatch.show_exceptions", "action_dispatch.show_detailed_exceptions", "action_dispatch.logger", "action_dispatch.backtrace_cleaner", "action_dispatch.key_generator", "action_dispatch.http_auth_salt", "action_dispatch.signed_cookie_salt", "action_dispatch.encrypted_cookie_salt", "action_dispatch.encrypted_signed_cookie_salt", "action_dispatch.cookies_serializer", "action_dispatch.cookies_digest", "action_dispatch.routes", "ROUTES_57612100_SCRIPT_NAME", "ORIGINAL_FULLPATH", "ORIGINAL_SCRIPT_NAME", "action_dispatch.request_id", "action_dispatch.remote_ip", "rack.session", "rack.session.options", "action_dispatch.request.path_parameters", "action_controller.instance", "action_dispatch.request.content_type", "action_dispatch.request.request_parameters", "rack.request.query_string", "rack.request.query_hash", "action_dispatch.request.query_parameters", "action_dispatch.request.parameters", "action_dispatch.request.formats", "rack.request.cookie_hash", "rack.request.cookie_string", "action_dispatch.cookies", "action_dispatch.request.unsigned_session_cookie"]
```
看起來好多了,但是這不好閱讀,我們試著讓他自己換行。
```
class KamigoController < ApplicationController
def eat
render plain: "吃土啦"
end
def request_headers
render plain: request.headers.to_h.keys.join("\n")
end
end
```
再加一個 `join("\n")`,試著把陣列轉成字串,並且以 `\n` 作為分隔符號,`\n` 其實是換行的意思。
```
rack.version
rack.errors
rack.multithread
rack.multiprocess
rack.run_once
SCRIPT_NAME
QUERY_STRING
SERVER_PROTOCOL
SERVER_SOFTWARE
GATEWAY_INTERFACE
REQUEST_METHOD
REQUEST_PATH
REQUEST_URI
HTTP_VERSION
HTTP_HOST
HTTP_CONNECTION
HTTP_CACHE_CONTROL
HTTP_USER_AGENT
HTTP_UPGRADE_INSECURE_REQUESTS
HTTP_ACCEPT
HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE
HTTP_COOKIE
HTTP_ALEXATOOLBAR_ALX_NS_PH
HTTP_IF_NONE_MATCH
SERVER_NAME
SERVER_PORT
PATH_INFO
REMOTE_ADDR
puma.socket
rack.hijack?
rack.hijack
rack.input
rack.url_scheme
rack.after_reply
puma.config
action_dispatch.parameter_filter
action_dispatch.redirect_filter
action_dispatch.secret_token
action_dispatch.secret_key_base
action_dispatch.show_exceptions
action_dispatch.show_detailed_exceptions
action_dispatch.logger
action_dispatch.backtrace_cleaner
action_dispatch.key_generator
action_dispatch.http_auth_salt
action_dispatch.signed_cookie_salt
action_dispatch.encrypted_cookie_salt
action_dispatch.encrypted_signed_cookie_salt
action_dispatch.cookies_serializer
action_dispatch.cookies_digest
action_dispatch.routes
ROUTES_57612100_SCRIPT_NAME
ORIGINAL_FULLPATH
ORIGINAL_SCRIPT_NAME
action_dispatch.request_id
action_dispatch.remote_ip
rack.session
rack.session.options
action_dispatch.request.path_parameters
action_controller.instance
action_dispatch.request.content_type
action_dispatch.request.request_parameters
rack.request.query_string
rack.request.query_hash
action_dispatch.request.query_parameters
action_dispatch.request.parameters
action_dispatch.request.formats
rack.request.cookie_hash
rack.request.cookie_string
action_dispatch.cookies
action_dispatch.request.unsigned_session_cookie
```
我們需要過濾掉不想看的東西,但是現在還是沒有很容易閱讀,我們應該排序一下。
```
def request_headers
render plain: request.headers.to_h.keys.sort.join("\n")
end
```
再加一個 `sort`,試著在轉完陣列後,先排序,再作排版文字。
```
GATEWAY_INTERFACE
HTTP_ACCEPT
HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE
HTTP_ALEXATOOLBAR_ALX_NS_PH
HTTP_CACHE_CONTROL
HTTP_CONNECTION
HTTP_COOKIE
HTTP_HOST
HTTP_IF_NONE_MATCH
HTTP_UPGRADE_INSECURE_REQUESTS
HTTP_USER_AGENT
HTTP_VERSION
ORIGINAL_FULLPATH
ORIGINAL_SCRIPT_NAME
PATH_INFO
QUERY_STRING
REMOTE_ADDR
REQUEST_METHOD
REQUEST_PATH
REQUEST_URI
ROUTES_57612100_SCRIPT_NAME
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
action_controller.instance
action_dispatch.backtrace_cleaner
action_dispatch.cookies
action_dispatch.cookies_digest
action_dispatch.cookies_serializer
action_dispatch.encrypted_cookie_salt
action_dispatch.encrypted_signed_cookie_salt
action_dispatch.http_auth_salt
action_dispatch.key_generator
action_dispatch.logger
action_dispatch.parameter_filter
action_dispatch.redirect_filter
action_dispatch.remote_ip
action_dispatch.request.content_type
action_dispatch.request.formats
action_dispatch.request.parameters
action_dispatch.request.path_parameters
action_dispatch.request.query_parameters
action_dispatch.request.request_parameters
action_dispatch.request.unsigned_session_cookie
action_dispatch.request_id
action_dispatch.routes
action_dispatch.secret_key_base
action_dispatch.secret_token
action_dispatch.show_detailed_exceptions
action_dispatch.show_exceptions
action_dispatch.signed_cookie_salt
puma.config
puma.socket
rack.after_reply
rack.errors
rack.hijack
rack.hijack?
rack.input
rack.multiprocess
rack.multithread
rack.request.cookie_hash
rack.request.cookie_string
rack.request.query_hash
rack.request.query_string
rack.run_once
rack.session
rack.session.options
rack.url_scheme
rack.version
```
我們需要觀察一下每一個 key 裡面包含的內容,來決定哪些是我們不要的。
```
def request_headers
render plain: request.headers.to_h.map{ |key, value|
key + ": " + value.class.to_s
}.sort.join("\n")
end
```
我們把 `keys` 改成了 `.map{ |key, value| key + ": " + value.class.to_s}`,map 的意思是把每一筆紀錄都拿去作一個轉換,然後傳回一個陣列。
如果我們是寫成 `.map{ |key, value| key }` 的話,就是每一筆紀錄我們只要保留關鍵字的部分,這樣就等於 `keys`,這兩段程式會有相同的結果。
但是因為我們想要看到更多的東西,所以我們再把 `key` 改寫成 `key + ": " + value.class.to_s`,我希望在每一個 key 後面加一個冒號,然後讓 Rails 告訴我,他們是什麼類型的資料。
得到的結果是這樣:
```
GATEWAY_INTERFACE: String
HTTP_ACCEPT: String
HTTP_ACCEPT_ENCODING: String
HTTP_ACCEPT_LANGUAGE: String
HTTP_ALEXATOOLBAR_ALX_NS_PH: String
HTTP_CACHE_CONTROL: String
HTTP_CONNECTION: String
HTTP_COOKIE: String
HTTP_HOST: String
HTTP_UPGRADE_INSECURE_REQUESTS: String
HTTP_USER_AGENT: String
HTTP_VERSION: String
ORIGINAL_FULLPATH: String
ORIGINAL_SCRIPT_NAME: String
PATH_INFO: String
QUERY_STRING: String
REMOTE_ADDR: String
REQUEST_METHOD: String
REQUEST_PATH: String
REQUEST_URI: String
ROUTES_57612100_SCRIPT_NAME: String
SCRIPT_NAME: String
SERVER_NAME: String
SERVER_PORT: String
SERVER_PROTOCOL: String
SERVER_SOFTWARE: String
action_controller.instance: KamigoController
action_dispatch.backtrace_cleaner: Rails::BacktraceCleaner
action_dispatch.cookies: ActionDispatch::Cookies::CookieJar
action_dispatch.cookies_digest: NilClass
action_dispatch.cookies_serializer: Symbol
action_dispatch.encrypted_cookie_salt: String
action_dispatch.encrypted_signed_cookie_salt: String
action_dispatch.http_auth_salt: String
action_dispatch.key_generator: ActiveSupport::CachingKeyGenerator
action_dispatch.logger: ActiveSupport::Logger
action_dispatch.parameter_filter: Array
action_dispatch.redirect_filter: Array
action_dispatch.remote_ip: ActionDispatch::RemoteIp::GetIp
action_dispatch.request.content_type: NilClass
action_dispatch.request.formats: Array
action_dispatch.request.parameters: ActiveSupport::HashWithIndifferentAccess
action_dispatch.request.path_parameters: Hash
action_dispatch.request.query_parameters: ActiveSupport::HashWithIndifferentAccess
action_dispatch.request.request_parameters: ActiveSupport::HashWithIndifferentAccess
action_dispatch.request.unsigned_session_cookie: Hash
action_dispatch.request_id: String
action_dispatch.routes: ActionDispatch::Routing::RouteSet
action_dispatch.secret_key_base: String
action_dispatch.secret_token: NilClass
action_dispatch.show_detailed_exceptions: TrueClass
action_dispatch.show_exceptions: TrueClass
action_dispatch.signed_cookie_salt: String
puma.config: Puma::Configuration
puma.socket: TCPSocket
rack.after_reply: Array
rack.errors: IO
rack.hijack: Puma::Client
rack.hijack?: TrueClass
rack.input: Puma::NullIO
rack.multiprocess: FalseClass
rack.multithread: TrueClass
rack.request.cookie_hash: Hash
rack.request.cookie_string: String
rack.request.query_hash: Hash
rack.request.query_string: String
rack.run_once: FalseClass
rack.session.options: ActionDispatch::Request::Session::Options
rack.session: ActionDispatch::Request::Session
rack.url_scheme: String
rack.version: Array
```
讓我們簡化一下程式碼
```
def request_headers
render plain: request.headers.to_h.map{ |key, value|
"#{key}: #{value.class}"
}.sort.join("\n")
end
```
`"#{key}: #{value.class}"` 是更加簡潔的表示法,用雙引號包裝的字串可以作變數的代換,語法是 `#{變數的名字}`,這種寫法的程式碼會更好閱讀。
看起來那些 `key` 包含 `action_controller`、`action_dispatch`、`puma`、`rack` 的資料都是我們不想看到的,因為他們看起來像是 Rails 這邊才產生的資料,而不是瀏覽器傳來的資料。
我發現這些我們不想要的 key 都包含 `.`,讓我們把在 `key` 包含 `.` 的資料都過濾掉。
```
def request_headers
render plain: request.headers.to_h.reject{ |key, value|
key.include? '.'
}.map{ |key, value|
"#{key}: #{value.class}"
}.sort.join("\n")
end
```
reject 可以過濾資料,滿足條件 `key.include? '.'` 的資料就沒有辦法進到 map。
得到的結果是這樣:
```
GATEWAY_INTERFACE: String
HTTP_ACCEPT: String
HTTP_ACCEPT_ENCODING: String
HTTP_ACCEPT_LANGUAGE: String
HTTP_ALEXATOOLBAR_ALX_NS_PH: String
HTTP_CACHE_CONTROL: String
HTTP_CONNECTION: String
HTTP_COOKIE: String
HTTP_HOST: String
HTTP_UPGRADE_INSECURE_REQUESTS: String
HTTP_USER_AGENT: String
HTTP_VERSION: String
ORIGINAL_FULLPATH: String
ORIGINAL_SCRIPT_NAME: String
PATH_INFO: String
QUERY_STRING: String
REMOTE_ADDR: String
REQUEST_METHOD: String
REQUEST_PATH: String
REQUEST_URI: String
ROUTES_57612100_SCRIPT_NAME: String
SCRIPT_NAME: String
SERVER_NAME: String
SERVER_PORT: String
SERVER_PROTOCOL: String
SERVER_SOFTWARE: String
```
現在應該可以試試看從顯示資料的類別改成顯示完整資料了。
```
def request_headers
render plain: request.headers.to_h.reject{ |key, value|
key.include? '.'
}.map{ |key, value|
"#{key}: #{value}"
}.sort.join("\n")
end
```
看起來像這樣:
```
GATEWAY_INTERFACE: CGI/1.2
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
HTTP_ACCEPT_ENCODING: gzip, deflate, br
HTTP_ACCEPT_LANGUAGE: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6
HTTP_ALEXATOOLBAR_ALX_NS_PH: AlexaToolbar/alx-4.0
HTTP_CACHE_CONTROL: max-age=0
HTTP_CONNECTION: keep-alive
HTTP_COOKIE: _blog_session=RG5tTnJ2eUIyMkFCUFV1UHFaMDhHbXpYekJXbFhQQlBiRlk1UEhucUkvV0IwcDNtV09sNUJuVTJWOS9RU2cweTgxY0Q1TGQ5L21GRWNmS1Z6RmdEa3cxdmxFUnZPOEJObVN3ck10R3Frc2ZOWXBDT2hNY0VZUUg0RHowNlJuazFXeWJXZE5sNjlsTUFBMG12QVJNRmVnPT0tLXo3dEJjUFJtbzRjSy9HODVNcVJRRVE9PQ%3D%3D--02e477b161398d92622542cb43d8b515892b8c59; _ironman_session=SzRPTlE1VytFbFgwRUkxMHlXaDFUVlpqdzN4ekt1eVFtUFpBbmtxNUw0UFd6cytjNkI1MlBOdC9zcnBkejNUMmxLa1MzdnV6Z0dselhHOTEzSUtJTDlrU241empqS1BmanNHSTBLd1VnVzlHV2pDZis4QVVRUk5xandJaGpPNml5VHlHUTI5ZXNCa1NZdHNrNzBYT0lnPT0tLW5salNpWUNVRmlxbUI1U1ZLdXhwMGc9PQ%3D%3D--c56c1473a20c57c62c66a215e07fa14dd6f7fb94
HTTP_HOST: localhost:3000
HTTP_IF_NONE_MATCH: W/"d220fb78d8ab10894ccdd2ef500f5ac8"
HTTP_UPGRADE_INSECURE_REQUESTS: 1
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
HTTP_VERSION: HTTP/1.1
ORIGINAL_FULLPATH: /kamigo/request_headers
ORIGINAL_SCRIPT_NAME:
PATH_INFO: /kamigo/request_headers
QUERY_STRING:
REMOTE_ADDR: 127.0.0.1
REQUEST_METHOD: GET
REQUEST_PATH: /kamigo/request_headers
REQUEST_URI: /kamigo/request_headers
ROUTES_57612100_SCRIPT_NAME:
SCRIPT_NAME:
SERVER_NAME: localhost
SERVER_PORT: 3000
SERVER_PROTOCOL: HTTP/1.1
SERVER_SOFTWARE: puma 3.11.0 Love Song
```
這應該就是從瀏覽器那邊傳來的全部內容了,我們可以用瀏覽器的 `F12` 看一下差異。
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVLQmK5-8hobOxHwM7fDPKwozabp4QBB9nD5y1M7uWUnAaoTC26qgdazr63oKr1QUt9wkA-fiJDXi8o0RsPvhj3fUCCoFsre9sLFP2mq84JNUx93Jx-yWeLfeUmbQ06-LUZF3Elf0CdVs/s1600/1.jpg)
因為這樣我們無法同時看到兩邊的結果,所以需要調整一下開發人員工具的位置,把他調到右側的話會比較恰當。
先點一下這裡:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi17I9Fn8peVszVuVCgrMpIzaXYW81_aPzQLwIxaecUaWtn9I1ktlyTrvsPUR7WlEhlT9PPzrgeEa45C_bX4L-rTUGbh-hg6orDO-IR0Ih_92jaqiQqovyUOo9wHhZ8HKe-_KaLlpWxZOo/s1600/2.jpg)
再點一下這裡:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSl6Rh2CGVY5PgklfbthWbO1HEtakh-mo6EmmpD61LYt-lO8LknqHYh8rLmA0USMTb-tQx7RMFrvOoduJkiAsFNizUiYprtxxviQq-L46dpZPk8OIL6lInWX0jgA0CgYhUui_pHrpa2rg/s1600/3.jpg)
點完之後應該會變成這樣:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgodGMjV9ohQIhJfHwtTraSHzSa5huE3sDYkq3iwLYrxFRooCd0I30fyBoXDtoKLEo6LVYq9_w6oE9Locc26T1JG414bQGzDhwjzMRxtnSSMMgkm9SShxDA-lUSzaSPOwmV3t7hO7Ycp6Y/s1600/4.jpg)
仔細一看,發現這兩塊是一樣的:
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_HKxX1Svx8CCBpNTgJnmav1jkJ71BN3c7xdOWaIKIUHHWKc0s07lZl8wvIFL2Aip8tSF2t0G-y3CDfWInp9uTUGJvQsvKtgWuo9X18ycAyRDIKcdIMukDnsQpibHVZ52KVbgVOL6Zscw/s1600/5.jpg)
# 從 Rails 觀察 request.body
再作一組 Route 和 Controller Action。
Route:
```
get '/kamigo/request_body', to: 'kamigo#request_body'
```
Action:
```
def request_body
render plain: request.body
end
```
用瀏覽器連過去看:[http://localhost:3000/kamigo/request_body](http://localhost:3000/kamigo/request_body),發現是 `#`,表示瀏覽器傳了一個空的 request body 過來,因為他是來下載網頁,不是上傳資料。如果是上傳資料的話,就會在 request body 有東西了。
# 從 Rails 觀察 response.headers
再作一組 Route 和 Controller Action。
Route:
```
get '/kamigo/response_headers', to: 'kamigo#response_headers'
```
Action:
```
def response_headers
render plain: response.headers.to_h.map{ |key, value|
"#{key}: #{value}"
}.sort.join("\n")
end
```
用瀏覽器連過去看:[http://localhost:3000/kamigo/response_headers](http://localhost:3000/kamigo/response_headers)。
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHNFQ0c4JSoIiOcWfbd23S1W32PgGer8tRw5LxDgPYe588Q_49amNbEyTZNzAv5fgyMLEtSNu3SheQSAyGrckphvd-SWOZ708uFxgQKr3LMDe98HuLyJ9HEFUF-x9Q956Uy45SJWWMI4g/s1600/6.jpg)
資料少很多,這表示 Rails 回傳的東西,不是全放在 `response.headers`,不過這不是很重要,知道有 `response` 這個東西就行了。
我們可以試著加一個 header 看看:
```
def response_headers
response.headers['5566'] = 'QQ'
render plain: response.headers.to_h.map{ |key, value|
"#{key}: #{value}"
}.sort.join("\n")
end
```
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW05FXWJNo1QOU3mDjAEhbHTKH97KppDbmgNZwglXEBiAKftpJiOf_5cUTmtYOpMj7khUSAofEvxRrg9sjM2pHsYzD8V5utjztugCaofwIyxPiaEsnNTK3FiMacbwYGf8mY5YRK2SuTvQ/s1600/7.jpg)
哈哈哈哈ㄚ哈
# 從 Rails 觀察 response.body
再作一組 Route 和 Controller Action。
Route:
```
get '/kamigo/response_body', to: 'kamigo#show_response_body'
```
Action:
```
def show_response_body
render plain: response.body
end
```
這裡我們不能用 `response_body` ,因為 `response_body` 已經被 Rails 用掉了,我們再用的話會出事,所以這邊稍微改一下名字。
用瀏覽器連過去看:[http://localhost:3000/kamigo/response_body](http://localhost:3000/kamigo/response_body)。
這樣會看到空的結果,因為我們傳回的內容就是 `response.body`,但此時的 `response.body` 其實還是空值。
所以我們必須改變一下觀察的方法,其實我們可以透過小黑框來觀察 Rails 的目前狀況。
在程式碼當中加入 `puts "媽我在這 \\( ̄▽ ̄)/"` 意思是把 `媽我在這 \\( ̄▽ ̄)/` 顯示在小黑框上。
```
def show_response_body
puts "媽我在這 \\( ̄▽ ̄)/"
render plain: response.body
end
```
當有人開啟網頁 [http://localhost:3000/kamigo/response_body](http://localhost:3000/kamigo/response_body),就會在小黑框看到這個結果:
```
Started GET "/kamigo/response_body" for 127.0.0.1 at 2018-01-03 03:46:48 +0800
Processing by KamigoController#show_response_body as HTML
媽我在這 \( ̄▽ ̄)/
Rendering text template
Rendered text template (0.0ms)
Completed 200 OK in 2ms (Views: 0.8ms)
```
所以我們利用這種方式觀察,現在把程式改成這樣:
```
def show_response_body
puts "===這是設定前的response.body:#{response.body}==="
render plain: "虎哇花哈哈哈"
puts "===這是設定後的response.body:#{response.body}==="
end
```
當有人開啟網頁 [http://localhost:3000/kamigo/response_body](http://localhost:3000/kamigo/response_body),就會在小黑框看到這個結果:
```
Started GET "/kamigo/response_body" for 127.0.0.1 at 2018-01-03 03:51:40 +0800
Processing by KamigoController#show_response_body as HTML
===這是設定前的response.body:===
Rendering text template
Rendered text template (0.0ms)
===這是設定後的response.body:虎哇花哈哈哈===
Completed 200 OK in 16ms (Views: 11.5ms)
```
# 總結
那個要抄程式碼的,都幫你整理好了。
### app/controllers/kamigo_controller.rb
```
class KamigoController < ApplicationController
def eat
render plain: "吃土啦"
end
def request_headers
render plain: request.headers.to_h.reject{ |key, value|
key.include? '.'
}.map{ |key, value|
"#{key}: #{value}"
}.sort.join("\n")
end
def response_headers
response.headers['5566'] = 'QQ'
render plain: response.headers.to_h.map{ |key, value|
"#{key}: #{value}"
}.sort.join("\n")
end
def request_body
render plain: request.body
end
def show_response_body
puts "===這是設定前的response.body:#{response.body}==="
render plain: "虎哇花哈哈哈"
puts "===這是設定後的response.body:#{response.body}==="
end
end
```
### config/routes.rb
```
Rails.application.routes.draw do
get '/kamigo/eat', to: 'kamigo#eat'
get '/kamigo/request_headers', to: 'kamigo#request_headers'
get '/kamigo/request_body', to: 'kamigo#request_body'
get '/kamigo/response_headers', to: 'kamigo#response_headers'
get '/kamigo/response_body', to: 'kamigo#show_response_body'
end
```
### 網址
[http://localhost:3000/kamigo/request_headers](http://localhost:3000/kamigo/request_headers)
[http://localhost:3000/kamigo/request_body](http://localhost:3000/kamigo/request_body)
[http://localhost:3000/kamigo/response_headers](http://localhost:3000/kamigo/response_headers)
[http://localhost:3000/kamigo/response_body](http://localhost:3000/kamigo/response_body)
今天就講到這裡。
嗯?今天是不是講太多了?
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言