programing

레일이 jQuery에서 JSON을 올바르게 디코딩하지 않음(배열이 정수 키를 가진 해시가 됨)

css3 2023. 3. 26. 11:41

레일이 jQuery에서 JSON을 올바르게 디코딩하지 않음(배열이 정수 키를 가진 해시가 됨)

JSON 오브젝트 배열을 jQuery에서 Rails로 POST 할 때마다 이 문제가 발생합니다.어레이 스트링을 지정하면 jQuery가 올바르게 동작하고 있음을 알 수 있습니다.

"shared_items"=>"[{\"entity_id\":\"253\",\"position\":1},{\"entity_id\":\"823\",\"position\":2}]"

다만, 어레이를 AJAX 콜의 데이터로서 송신하면, 다음과 같이 됩니다.

"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}

한편, 플레인 어레이를 송신하는 것만으로 동작합니다.

"shared_items"=>["entity_253"]

Rails가 어레이를 이상한 해시로 변경하는 이유는 무엇입니까?여기에 유형이 없기 때문에 Rails가 내용을 올바르게 이해할 수 없기 때문입니다(jQuery 호출에서 설정하는 방법이 있습니까?).

Processing by SharedListsController#create as 

감사해요!

업데이트: 데이터를 문자열이 아닌 어레이로 전송하며 어레이는 다음 명령을 사용하여 동적으로 생성됩니다..push()기능.로 시험해 보았다.$.post ★★★★★★★★★★★★★★★★★」$.ajax 결과입니다

만약 누군가가 이것을 우연히 발견하여 더 나은 해결책을 원할 경우, 당신은 '콘텐츠'를 지정할 수 있습니다..ajax 호출에 'application/json' 옵션을 입력하고 Rails가 JSON 개체를 모두 문자열 값을 가진 정수 키 해시로 구분하지 않고 적절하게 구문 분석하도록 합니다.

요약하자면, 제 문제는 다음과 같습니다.

$.ajax({
  type : "POST",
  url :  'http://localhost:3001/plugin/bulk_import/',
  dataType: 'json',
  data : {"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]}
});

결과적으로 Rails는 다음과 같이 해석하게 되었습니다.

Parameters: {"shared_items"=>{"0"=>{"entity_id"=>"253", "position"=>"1"}, "1"=>{"entity_id"=>"823", "position"=>"2"}}}

반면 (주의: 이제 javascript 객체를 문자열화하고 내용 유형을 지정하므로 레일에서 문자열을 해석하는 방법을 알 수 있습니다.)

$.ajax({
  type : "POST",
  url :  'http://localhost:3001/plugin/bulk_import/',
  dataType: 'json',
  contentType: 'application/json',
  data : JSON.stringify({"shared_items": [{"entity_id":"253","position":1}, {"entity_id":"823","position":2}]})
});

레일에서 좋은 객체가 생성됩니다.

Parameters: {"shared_items"=>[{"entity_id"=>"253", "position"=>1}, {"entity_id"=>"823", "position"=>2}]}

Ruby 1.9.3에서는 Rails 3에서 사용할 수 있습니다.

조금 오래된 질문이지만, 제가 오늘 이것과 싸웠습니다.그리고 제가 생각해낸 답은 다음과 같습니다.이것은 약간 jQuery의 잘못이라고 생각합니다만, 이것은 당연한 것입니다.하지만 해결 방법이 있습니다.

다음 jQuery ajax 콜이 지정됩니다.

$.ajax({
   type : "POST",
   url :  'http://localhost:3001/plugin/bulk_import/',
   dataType: 'json',
   data : {"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}]}

});

jQuery가 게시하는 값은 다음과 같습니다(Fire-bug-of-choice의 Request를 참조하면 다음과 같은 폼 데이터를 얻을 수 있습니다).

shared_items%5B0%5D%5Bentity_id%5D:1
shared_items%5B0%5D%5Bposition%5D:1

CGI.unencode를 실행하면

shared_items[0][entity_id]:1
shared_items[0][position]:1

이는 jQuery가 JSON의 이러한 키가 폼 요소 이름이며 "user[name]"이라는 필드가 있는 것처럼 취급해야 한다고 생각하기 때문이라고 생각합니다.

즉, Rails 앱에 들어오면 Rails는 대괄호를 보고 필드 이름의 가장 안쪽 키(jQuery가 "도움이 되는" "1")를 유지하는 해시를 작성합니다.

어쨌든, 이 동작을 회피하기 위해서, 다음과 같은 방법으로 ajax 콜을 작성했습니다.

$.ajax({
   type : "POST",
   url :  'http://localhost:3001/plugin/bulk_import/',
   dataType: 'json',
   data : {"data": JSON.stringify({"shared_items": [{"entity_id":"253","position":1},{"entity_id":"823","position":2}])},
  }
});

따라서 jQuery는 이 JSON이 Javascript 객체가 아닌 사용자가 전달하고 싶은 이라고 생각하고 모든 키를 폼 필드명으로 변환해야 합니다.

단, 이는 JSON을 파라미터[:data]로 명시적으로 디코딩해야 하기 때문에 Rails 측에서는 상황이 약간 다르다는 것을 의미합니다.

하지만 괜찮습니다.

ActiveSupport::JSON.decode( params[:data] )

TL;DR: 해결책은 다음과 같습니다.jQuery.ajax() 호출에 대한 데이터 파라미터에서{"data": JSON.stringify(my_object) }명시적으로 JSON 배열을 jQuery에 입력하지 않고(이 경우 JSON 배열을 사용하여 무엇을 할지 잘못 추측합니다).

방금 Rails 4에서 이 문제가 발생했습니다.질문에 명시적으로 대답하려면("Rails가 어레이를 이상한 해시로 변경하는 이유") 액션 컨트롤러에 대한 레일즈 가이드의 섹션 4.1을 참조하십시오.

값 배열을 보내려면 키 이름에 빈 대괄호 "[]" 쌍을 추가합니다.

문제는 jQuery가 빈 대괄호 대신 명시적 배열 인덱스로 요청을 포맷한다는 것입니다. 「」를 송신하는 , 「」를 송신하는 것입니다.shared_items[]=1&shared_items[]=2 , 을 보냅니다.shared_items[0]=1&shared_items[1]=2 해시: Rails로 합니다.{ shared_items: { '0' => '1', '1' => '2' } }.

클라이언트를 제어할 수 없는 경우 해시를 배열로 변환하여 서버 측에서 이 문제를 해결할 수 있습니다.방법은 다음과 같습니다.

shared_items = []
params[:shared_items].each { |k, v|
  shared_items << v
}

강력한 매개 변수를 사용하는 경우 다음 방법이 유용할 수 있습니다.

def safe_params
  values = params.require(:shared_items)
  values = items.values if items.keys.first == '0'
  ActionController::Parameters.new(shared_items: values).permit(shared_items: [:entity_id, :position]).require(:shared_items)
end

은 '아예'를 해 본 적이 ?parsed_json = ActiveSupport::JSON.decode(your_json_string)다른 방법으로 물건을 보내는 경우.to_json데이터를 직렬화합니다.

JSON 문자열을 Rails 컨트롤러 동작에 넣으려고 하는 것 뿐입니까?

Rails가 해시를 가지고 무엇을 하고 있는지는 모르겠지만, Javascript/J를 작성하면 문제를 해결할 수 있을 것입니다.SON 오브젝트(JSON 스트링이 아닌 것)로, Ajax 콜의 데이터 파라미터로서 송신합니다.

myData = {
  "shared_items":
    [
        {
            "entity_id": "253",
            "position": 1
        }, 
        {
            "entity_id": "823",
            "position": 2
        }
    ]
  };

이것을 ajax 경유로 송신하는 경우는, 다음과 같은 조작을 실시합니다.

$.ajax({
    type: "POST",
    url: "my_url",    // be sure to set this in your routes.rb
    data: myData,
    success: function(data) {          
        console.log("success. data:");
        console.log(data);
    }
});

위의 ajax 스니펫을 통해 jQuery는 dataType에 대해 인텔리전트한 추측을 할 수 있습니다.다만, 통상은 명시적으로 지정하는 것이 좋습니다.

어느 쪽이든 컨트롤러 동작에서 파라미터 해시를 사용하여 전달한 JSON 개체를 가져올 수 있습니다.

params[:shared_items]

예: 이 동작은 json 개체를 사용자에게 다시 뱉습니다.

def reply_in_json
  @shared = params[:shared_items]

  render :json => @shared
end

rack-jquery-params gem을 사용합니다(면책자:제가 작가입니다.)어레이가 정수 키로 해시가 되는 문제를 해결합니다.

언급URL : https://stackoverflow.com/questions/6410810/rails-not-decoding-json-from-jquery-correctly-array-becoming-a-hash-with-intege