2017-01-11 60 views
1

我正在研究一個酒店聚合網站,它允許用戶調整過濾器(例如價格或客人數量)並通過ajax查看住宿設施的可用性。它基於使用CoffeeScript和Jquery的Rails 4構建。Rails/Jquery Ajax - SyntaxError:意外的標識符,但JSON有效

這裏是JQuery的調用(CoffeeScript的):時間

$.ajax '/accommodations/show', 
     type: 'GET' 
     dataType : 'script' 
     data: 
     privates: include_privates 
     shared: include_shared 
     homes: include_homes 
     price_range: price_range 
     start_date: start_date 
     end_date: end_date 
     num_guests: num_guests 
     success: (data) -> 
     #RESPONSE DOES NOT HAPPEN HERE, IS HANDLED IN SHOW.JS.ERB 
     console.log "Success!" 
     console.log data 
     error: (data, status, error) -> 
     console.log 'How embarassing! Something went wrong - please try your search again. ' 
     console.log "Status: #{status}" 
     console.log "Error: #{error}" 

90%,此代碼的工作。當時的另外10%,服務器返回200種狀態(好),但Jquery的失敗,控制檯顯示以下內容:

How embarassing! Something went wrong - please try your search again. 
Status: parsererror 
Error: SyntaxError: Unexpected identifier 

這個問題每隔計算器問題看起來好像是正在傳遞無效的JSON回到Jquery。我找到了show.js.coffee.erb中的問題行。這是我們將rails模型轉換爲JSON的地方,所以它可以傳遞給javascript。

$('.refresh-loading').hide() 
//Adding the accommodation modules to the left-hand side 
$('#accommodation-modules-wrapper').html("<%= escape_javascript(render partial: 'accommodations/accomm_modules', locals: {properties: @accommodations, slider_min: @price_low, slider_max: @price_high})%>") 
window.init_isotope() 

//Removing the loading icon 
$('.refresh-loading').hide() 

//THIS IS WHERE THE ERROR IS 
//Removing this line fixes the issue 
marker_string = '<script>window.accommodation_markers = <%= raw @accommodations.to_json %>;</script>' 

raw @accommodations.to_json的輸出是下面的:

[{ 
    "id": 741580, 
    "name": "Gamer's Paradise in Brooklyn!", 
    "google_place_id": "ChIJOwg_06VPwokRYv534QaPC8g", 
    "type_code": "hotel", 
    "external_id": 2243038, 
    "lat": 40.694426, 
    "lng": -73.94636, 
    "location_rating": 9.0, 
    "overall_rating": 9.0, 
    "review_count": 13, 
    "currency_code": "USD", 
    "average_nightly_price": 30.0, 
    "image_url": "https://a2.muscache.com/im/pictures/asdfa-4cf7-4222-9204-619200def457.jpg?aki_policy=small", 
    "url": "https://www.test.com/rooms/13396285", 
    "review_url": "https://www.test.com/rooms/13396285#reviews", 
    "accommodation_cluster_id": null, 
    "created_at": "2016-12-07T11:22:21.319-08:00", 
    "updated_at": "2016-12-14T08:48:51.073-08:00", 
    "usd_average_nightly_price": "30.0", 
    "city_rank": 0, 
    "city_rank_price": 15, 
    "city_rank_reviews": 511, 
    "cluster_rank": 0, 
    "cluster_rank_price": 0, 
    "cluster_rank_reviews": 1, 
    "shared_room": true, 
    "private_room": false, 
    "entire_home": false, 
    "external_uid": null 
}] 

該輸出根據JSONLint是有效的。我如何去進一步調試和解決這個問題?

+1

@PaulRoub在這一個似乎是正確的。雖然你應該在將它分配給實例變量之前轉換成json,如果你仍然有問題,那麼在那裏驗證。 – Jeff

+0

@Jeff - 如果我在控制器方法中進行轉換(即'原始'),我仍然有同樣的問題。 – CHawk

+1

您是如何在控制器操作中驗證它的?當它不起作用時,您是否複製了一個實例的散列? – Jeff

回答

1

讓我們從一個簡化的例子開始,看看會發生什麼。如果你有這樣的紅寶石:

@thing = { :id => 741580, :name => "Gamer's Paradise in Brooklyn!" } 

,然後在一些ERB你說:

thing = '<%=raw @thing.to_json %>' 

那麼你會認爲這是輸出:

thing = '{"id":741580,"name":"Gamer's Paradise in Brooklyn!"}' 

而且是你的問題:raw<%= ... %>都不會引用/轉義/編碼'raw調用只是告訴ERB引擎不要對其參數進行HTML編碼,而且您沒有針對HTML,因此您在組合中使用了raw功能。但是你想要更多,你想讓這些引號逃脫。

可能最簡單的做法是使用String#html_safeescape_javascript。但是你在由ERB生成的JavaScript字符串中有JavaScript,所以你需要加倍轉義;不愉快的事情,如:

marker_string = '<script>window.accommodation_markers = <%= escape_javascript(escape_javascript(@accommodations.to_json.html_safe)) %>;</script>' 

我強烈向重構的東西傾斜,使「<script>一個JavaScript字符串裏」是沒有必要兩輪牛車。三層編碼/轉義有點多,而且很容易出錯。

相關問題