簡體   English   中英

在Rails 4中以“普通” javascript(無jQuery)發布AJAX請求

[英]Post AJAX request in “vanilla” javascript, no jQuery, in Rails 4

我已經完成了谷歌搜索並尋找解決方案,但由於我的項目異常奇怪,所以沒有找到可靠的解決方案。

我正在嘗試僅使用“香草” javascript(不允許使用jQuery或Rails助手)制作一個帶有Rails 4后端的簡單聊天應用程序。 我有一個GET Ajax請求,該請求將收集所有種子消息數據並將其顯示在聊天中。 但是,當我嘗試向Rails后端寫入POST請求時,我遇到了兩個主要問題。 它們可能彼此相關,也可能彼此不相關。

我暫時克服的第一個問題是422狀態錯誤(無法處理的實體)。 我相信這是因為我的xmlhttp.setRequestHeader值錯誤嗎?
但是,我不知道它們還應該是什么。 我通過在我的Rails MessagesController中放置一個skip_before_filter :verify_authenticity_token暫時解決了這個問題。
有解決這個問題的更優雅的方法嗎?

這導致我遇到下一個問題,即400狀態錯誤(錯誤請求)。 當我在運行服務器時在終端上查看錯誤時,問題看起來像...

在2014-11-26 17:32:48 -0800為127.0.0.1開始發布POST“ / messages”
由MessagesController#create處理為* / *
參數:{“ user” =>“ namechatsample”,“ content” =>“ messageagechatsample”}
在4毫秒內完成了400個錯誤請求

ActionController :: ParameterMissing(參數缺失或值為空:消息):app / controllers / messages_controller.rb:17:在message_params' app/controllers/messages_controller.rb:9:in創建中

任何指導和幫助將不勝感激!

這是我的代碼。

Ajax通話

var getRequest = function(callback) {
  var xmlhttp;
  if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
  } else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4) {
      if (xmlhttp.status == 200) {
        data = JSON.parse(xmlhttp.responseText);
        callback(data.messages)
      } else if (xmlhttp.status == 400) {
        alert('There was an error 400 for GET')
      } else {
        alert('something else other than 200 was returned for GET! This status is ' + xmlhttp.status)
      }
    }
  }
  xmlhttp.open("GET", "/messages", true);
  xmlhttp.send();
}


var postRequest = function(user, message) {
  var xmlhttp;
  if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
  } else {
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4) {
      if (xmlhttp.status == 200) {
        data = JSON.parse(xmlhttp.responseText);
        alert('Post ajax call was a success')
      } else if (xmlhttp.status == 400) {
        alert('There was an error 400 for POST')
      } else {
        alert('something else other than 200 was returned for POST! The status is ' + xmlhttp.status)
      }
    }
  }
  xmlhttp.open("POST", "/messages", true);
  xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xmlhttp.send("user=" + user + "&content=" + message + "");
}

postRequest("namechatsample", "messsagechatsample")

Rails 4消息控制器

class MessagesController < ApplicationController
 skip_before_filter  :verify_authenticity_token

 def index #returns last 10 messages
   render :json => Message.last(10)
 end

 def create #makes a new message
   msg = Message.new(message_params)
   msg.save
   render :json => msg
 end


 private
  def message_params
    params.require(:message).permit(:user, :content)
  end
end

如果您認為其他文件或代碼位置中存在問題,請告訴我!

422狀態錯誤

422錯誤是因為默認情況下,Rails通過真實性令牌添加了跨站點請求偽造(CSRF)預防措施 如果令牌在422處無效(或不存在),則在POST/PUT/DESTROY請求中返回錯誤狀態。 為了解決這個問題,您可以禁用真實性檢查(就像您已經做過的那樣),或者可以按照此答案中的說明在ajax請求中發送所需的令牌

400狀態錯誤

這是因為您在控制器中定義的強參數要求將message參數作為發送的參數的一部分( params.require(:message)... ),並且它允許將“ content”值作為嵌套參數。 例如,所需的結構必須為:

:message => {:content => 'message data'}

在javascript中,您已將消息的參數名稱發送為“內容”,該參數名稱必須為“ message [內容]”。 例如:

xmlhttp.send("message[user]=" + user + "&message[content]=" + message + "");

你有:

 def message_params
     params.require(:message).permit(:user, :content)
 end

這要求將強參數傳遞給請求中的控制器。 根據此聲明,json必須看起來像

 {"message" : {"user" : "someuserthing", "content" : "someusercontent"}}

看起來您還差得遠,但是確保您的應用正在以這種格式傳遞JSON是第一步。

順便說一句,在控制台中查看實際傳遞的json是非常有用的。 對於您的情況,您說:

 Parameters: {"user"=>"namechatsample", "content"=>"messsagechatsample"}

如您所見,它沒有“消息”的根元素。

祝好運。

這導致我遇到下一個問題,即400狀態錯誤(錯誤請求)

require(:message) ,但僅發送usercontent

有解決這個問題的更優雅的方法嗎?

是的,如果您根本不想處理CSRF,可以將其放在application.rb

self.allow_forgery_protection = false

或者,您可以實施適當的CSRF處理。 :)

但是,讓我添加一個不請自來的問題:Rails不太適合聊天應用程序。 理想情況下,您需要像彗星般的東西,例如socket.io。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM