一直以來,我們都是用瀏覽器發出 HTTP request
,打到我們的 Rails Server,然後我們的 Rails Server 再傳回 HTTP Response
。
我們還沒有試過用 Rails Server 發出 HTTP request
,今天就來試一下。
用 Rails 發 HTTP request
Routes
在 config/routes.rb
加入
get '/kamigo/sent_request', to: 'kamigo#sent_request'
Action
在 app/controllers/kamigo_controller.rb
加入
def sent_request
uri = URI('http://localhost:3000/kamigo/response_body')
response = Net::HTTP.get(uri)
render plain: response
end
這是最簡單能發出 Request
的方法,我們先把網址字串轉換成 URI
物件,透過 Net::HTTP.get
這個方法,他會接受一個網址,然後把 Response
的 Body
部分以字串的形式傳回。在這段程式裡面我們只能看到傳入網址跟最終結果,我們不能調整 Request Header
和 Request Body
,也不能觀察 Response Header
。
我讓他連去 http://localhost:3000/kamigo/response_body,這是我們昨天作好的東西。
在瀏覽器開啟網址
網址:http://localhost:3000/kamigo/sent_request 開啟網址後會看到:
虎哇花哈哈哈
小黑框的顯示結果
Started GET "/kamigo/sent_request" for 127.0.0.1 at 2018-01-04 01:06:38 +0800
Processing by KamigoController#sent_request as HTML
Started GET "/kamigo/response_body" for 127.0.0.1 at 2018-01-04 01:06:39 +0800
Processing by KamigoController#show_response_body as */*
===這是設定前的response.body:===
Rendering text template
Rendered text template (0.0ms)
===這是設定後的response.body:虎哇花哈哈哈===
Completed 200 OK in 344ms (Views: 9.2ms)
Rendering text template
Rendered text template (0.0ms)
Completed 200 OK in 1400ms (Views: 2.7ms)
突然想到有個東西還沒講,那就是 Ruby 的函數。
Ruby 的函數
一個函數可以把一個東西變成另一個東西,或者把多個東西變成另一個東西。
舉個例:我們來作一個函數,輸入是一句話,我們要把這句話變成韓文。
函數宣告
def translate_to_korean(message)
"#{message}油~"
end
一個函數裡面可以寫一段程式,最後一行程式的執行結果就會是函數的傳回值。
不管傳入什麼,我們就在後面加上油~
。
函數呼叫
translate_to_korean('愛老虎')
你想要使用小括號或者使用空白框住傳入的參數都可以。
translate_to_korean '愛老虎'
結果
"愛老虎油~"
成功翻譯成韓文!
把翻譯韓文的功能加入到上面的爬蟲
修改 Action
def sent_request
uri = URI('http://localhost:3000/kamigo/response_body')
response = Net::HTTP.get(uri)
render plain: translate_to_korean(response)
end
開啟網頁
壞掉囉,錯誤訊息是 incompatible character encodings: ASCII-8BIT and UTF-8
。
下面那個深灰色區域是給我們除錯用的,有點類似 irb
,我們可以在下面輸入一點東西:
我輸入了 message
,看看 message 的值是什麼,結果看到是這樣:
>> message
=> "\xE8\x99\x8E\xE5\x93\x87\xE8\x8A\xB1\xE5\x93\x88\xE5\x93\x88\xE5\x93\x88"
>>
因為我們獲得的 response 字串的編碼是 ASCII-8BIT
,沒辦法直接跟 UTF-8
編碼的 "油~" 加在一起。
所以修正的方法就是把 response 字串轉碼為 UTF-8 即可:
再次修改 Action
def sent_request
uri = URI('http://localhost:3000/kamigo/response_body')
response = Net::HTTP.get(uri).force_encoding("UTF-8")
render plain: translate_to_korean(response)
end
在字串後面寫 .force_encoding("UTF-8")
就可以把編碼轉為 UTF-8
格式了。
再次開啟網頁
虎哇花哈哈哈油~
玩樂時間結束,來作點正事,目前的寫法沒辦法觀察 request
和 response
,我們需要能觀察 request
和 response
的寫法。
能觀察 request 和 response 的寫法
修改 Action
def sent_request
uri = URI('http://localhost:3000/kamigo/eat')
http = Net::HTTP.new(uri.host, uri.port)
http_request = Net::HTTP::Get.new(uri)
http_response = http.request(http_request)
render plain: JSON.pretty_generate({
request_class: request.class,
response_class: response.class,
http_request_class: http_request.class,
http_response_class: http_response.class
})
end
越來越複雜了。通常要作到細膩的控制,就要寫比較多的程式碼。
我們先觀察一下這四個物件:request
、response
、http_request
、http_response
,前兩個是 Rails 內建的,後兩個是我們在 Action 中定義的,為了能夠同時輸出 4 個字串,我用一個雜湊陣列把想看的字串都放進去,然後使用
JSON.pretty_generate
幫我排成比較好閱讀的格式,讓我們來看一下個別對應的類別:
開啟網頁
{
"request_class": "ActionDispatch::Request",
"response_class": "ActionDispatch::Response",
"http_request_class": "Net::HTTP::Get",
"http_response_class": "Net::HTTPOK"
}
圖解
昨天我們學的是 1
跟 4
,今天學 2
跟 3
,這裡的四個物件,都是屬於不同的類別,所以我們可能需要不同的語法去存取他們。
今天只要了解到這裡就行了。
總結
- 不是只有瀏覽器才能發出 HTTP Request,網頁伺服器一樣可以發出 HTTP Request
- 今天學會了宣告函數和呼叫函數的正確觀念。
明天講怎麼讓別人能連到你作的網站。
沒有留言:
張貼留言