2011-12-14 44 views
8

假設你有一個網址的Rails:查詢參數VS之後的參數

localhost:3000?a=1 

,並在請求中,你也有一個之後的參數

a=2 

params[:a]在這個什麼案件? 它依賴於HTTP動詞嗎?

如果它不依賴於HTTP動詞,

如果你的形式看起來像

<form method='post' action='/?a=2'> 
    <input type='hidden' name='a' value='3'/> 
</form> 

會有什麼params[:a]在這種情況下?

UPDATE

所以,我只是做了一個小實驗,使用Chrome的調試器附加?authenticity_token=abc行動網址。我查看了服務器日誌,發現參數有authenticity_token => 'abc'。我也相信這種情況下的方法是POST

讓我知道你們想出了什麼。

回答

18

當我在示例代碼中嘗試了這一點時,我能夠看到的是查詢參數(GET)優先於POST主體。於是,我開始研究處理Rails中HTTP請求的代碼Rack。下面是從request.rb

# Returns the data recieved in the query string. 
def GET 
    .... 
end 

# Returns the data recieved in the request body. 
# 
# This method support both application/x-www-form-urlencoded and 
# multipart/form-data. 
def POST 
    .... 
end 

# The union of GET and POST data. 
def params 
    @params ||= self.GET.merge(self.POST) 
rescue EOFError 
    self.GET 
end 

這裏,方法的代碼

  • GET - 返回哈希格式的查詢參數
  • POST - 返回後身體在哈希格式

因此,根據params的代碼,在參數相同的情況下,GET參數應該被POST參數覆蓋。 (self.GET.merge(self.POST))。但是,這與我在實際嘗試時得到的結果相反。

所以,唯一的機會是這段代碼被Rails覆蓋。當我想到它時,它非常有意義,因爲來自Rails的params散列將始終包含"controller""action"鍵,在Rack中將不存在這些鍵。所以,我也查看了Rails的代碼,並發現params方法確實被覆蓋。在Rails源代碼中查看request.rbparameters.rb。在parameters.rb,我們有:

# Returns both GET and POST \parameters in a single hash. 
    def parameters 
    @env["action_dispatch.request.parameters"] ||= begin 
     params = request_parameters.merge(query_parameters) 
     params.merge!(path_parameters) 
     encode_params(params).with_indifferent_access 
    end 
    end 
    alias :params :parameters 

request.rb

# Override Rack's GET method to support indifferent access 
def GET 
    @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {}) 
end 
alias :query_parameters :GET 

# Override Rack's POST method to support indifferent access 
def POST 
    @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {}) 
end 
alias :request_parameters :POST 

所以,在這裏

  • query_parameters - 別名GET方法
  • REQUEST_PARAMETERS - 別名的POST方法
  • path_parameters - 方法ret甕的請求作爲哈希
  • 參數控制器和行動 - 爲params別名(就是在這裏覆蓋)

注意,GET方法和POST方法也被覆蓋,主要是轉換散列返回到HashWithIndifferentAccess的對象。

因此,在這裏查看代碼(params = request_parameters.merge(query_parameters)),顯然在Rails中,在參數相同的情況下,POST參數被GET參數覆蓋。換句話說,GET參數優先於POST參數。

1

這將是2.但是對於路由,它將匹配'1'。

如果你願意,你可以使用request.GET和request.POST來訪問get和post vars。

1

不,它不依賴於de HTTP動詞,但你肯定可以採取不同的動作來處理GETPOST,或者它可以是相同的,你會在兩種情況下都得到`params [:a]。

+0

我可能寫了我的問題很差,但我的問題是,如果有post param和查詢參數與相同的密鑰,並通過POST方法請求。哪個優先於哪個? – denniss 2011-12-14 20:03:22

+0

剛做了一個測試,輸入值被忽略,然後`form`標籤中的一個獲得優先級。 – 2011-12-14 20:15:24

+0

真棒謝謝!我也得到了同樣的東西=) – denniss 2011-12-14 20:27:04

6

Rails usesRack::Request HTTP請求。但是,它重新定義ActionDispatch::Http::Parameters中的Rackparams方法(通過別名)。

params方法,它返回請求參數,是這樣實現的:

# Returns both GET and POST \parameters in a single hash. 
    def parameters 
    @env["action_dispatch.request.parameters"] ||= begin 
     params = request_parameters.merge(query_parameters) 
     params.merge!(path_parameters) 
     encode_params(params).with_indifferent_access 
    end 
    end 
    alias :params :parameters 

注別名parameters方法。

除非重新定義,否則查詢字符串中的參數將覆蓋POST正文中的參數。