iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 15
8
Modern Web

只要有心,人人都可以做卡米狗系列 第 15

第十五天:從 Rails 認識 HTTP 協定

昨天我們學會了怎麼新增 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

你會看到:

#<ActionDispatch::Http::Headers:0x0000000007ead268>

表示 request.headers 是一個 ActionDispatch::Http::Headers 物件,但是其實我們想知道的是他包含的內容是什麼,而不是他是什麼類別的物件。

從 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_controlleraction_dispatchpumarack 的資料都是我們不想看到的,因為他們看起來像是 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 看一下差異。

因為這樣我們無法同時看到兩邊的結果,所以需要調整一下開發人員工具的位置,把他調到右側的話會比較恰當。

先點一下這裡:

再點一下這裡:

點完之後應該會變成這樣:

仔細一看,發現這兩塊是一樣的:

從 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,發現是 #<Puma::NullIO:0x000000000673ae00>,表示瀏覽器傳了一個空的 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

資料少很多,這表示 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

哈哈哈哈ㄚ哈

從 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

這樣會看到空的結果,因為我們傳回的內容就是 response.body,但此時的 response.body 其實還是空值。

所以我們必須改變一下觀察的方法,其實我們可以透過小黑框來觀察 Rails 的目前狀況。

在程式碼當中加入 puts "媽我在這 \\( ̄▽ ̄)/" 意思是把 媽我在這 \\( ̄▽ ̄)/ 顯示在小黑框上。

  def show_response_body
    puts "媽我在這 \\( ̄▽ ̄)/"
    render plain: response.body
  end

當有人開啟網頁 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,就會在小黑框看到這個結果:

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_body

http://localhost:3000/kamigo/response_headers

http://localhost:3000/kamigo/response_body

今天就講到這裡。

嗯?今天是不是講太多了?


上一篇
第十四天:最基本的 Rails 運作流程
下一篇
第十六天:做一個最簡單的爬蟲
系列文
只要有心,人人都可以做卡米狗33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
魷魚
iT邦新手 1 級 ‧ 2018-01-09 15:37:06
 def response_headers
    render plain: response.headers.to_h.map{ |key, value|
      "#{key}: #{value}"
    }.sort.join("\n")
  end

這行程式我不小心把render plain: response.headers這段打成render plain: response_headers,然後當我用網址去觀看時,我的rails服務就掛掉了。按Ctrl+C也無法退出,只能關閉再一次。請問如果遇到類似的狀況有其他解法嗎?
https://ithelp.ithome.com.tw/upload/images/20180109/20103350B2AH7YSa1V.jpg

等久一點他可能會停下來 XD

因為剛好 response_headers 是函數名稱。

舉個例:

def aaa
  aaa
end

這個函數會一直不斷地呼叫自己,不會停止。跑個幾萬次之後到達一個臨界點才會停下來。你遇到的就是這個問題。

魷魚 iT邦新手 1 級 ‧ 2018-01-09 17:27:34 檢舉

我有等他跑到終點過,但跑到終點後網頁服務器就掛掉了,只能重開cmd。測試時常常打錯指令,要一直重開服務器,所以才想說有沒有其他辦法:D
謝謝你幫我解惑/images/emoticon/emoticon41.gif

sky54063 iT邦新手 5 級 ‧ 2019-04-12 14:15:12 檢舉

請問一下,我照著做可是卻不知道為什麼執行不出來,再麻煩協助看一下,謝謝。
https://imgur.com/CjOeS2R
https://imgur.com/Dl2AbOP
https://imgur.com/2ktqSzZ

0
james10949
iT邦新手 5 級 ‧ 2018-02-09 08:48:34

https://ithelp.ithome.com.tw/upload/images/20180209/20108677TCFq8Svmn1.jpghttps://ithelp.ithome.com.tw/upload/images/20180209/20108677QRsS4uMzgI.jpg
Again (QUQ)

看更多先前的回應...收起先前的回應...

好吧
我發現我打錯字了 XD

XD

https://ithelp.ithome.com.tw/upload/images/20180209/20108677l8y3TRTMSk.jpg
從 Rails 觀察 request.body那段出問題了
求解
https://ithelp.ithome.com.tw/upload/images/20180209/20108677B1OADGPTdo.jpg
https://ithelp.ithome.com.tw/upload/images/20180209/20108677hD6OxTcSZH.jpg

你是不是把 alpha 打成 beta 了?

0
patyhank
iT邦新手 5 級 ‧ 2018-07-05 13:05:41

這次好長阿

0
sky54063
iT邦新手 5 級 ‧ 2019-04-15 11:20:11

請問一下,我照著做可是卻不知道為什麼執行不出來,再麻煩協助看一下,謝謝。
https://imgur.com/CjOeS2R
https://imgur.com/Dl2AbOP
https://imgur.com/2ktqSzZ

你的輸入錯了哦,是

render plain: request.headers

不是

render plain: request_headers

你輸入 request_headers 的時候,因為你前面寫了

def request_headers

所以系統認為你在呼叫方法,然後他就一直自己叫自己,就卡死了。

0
jian_wei
iT邦新手 5 級 ‧ 2019-05-09 21:04:09

想觀察request.headers 打127.0.0.1 跑出這個畫面https://ithelp.ithome.com.tw/upload/images/20190509/20115672RxM7aczjZy.png
之前測的時候還好好的
https://ithelp.ithome.com.tw/upload/images/20190509/20115672SZAKXAPib2.png

jian_wei iT邦新手 5 級 ‧ 2019-05-10 15:34:44 檢舉

以自行解決><

我要留言

立即登入留言