2016-05-19 131 views
-1

您好我傳遞在捲曲命令ID的在紅寶石應用陣列經由%通過在捲曲數組x(),但我無法添加這些投擲誤差爲:無法使用紅寶石%x命令

JSON_PARSING_ERROR: Unexpected character (d) at position 

陣列:@m = ["d_sample_id1","d_sample_id2"]

使用的命令:

%x(curl --header 'Authorization: key=keynotmentioned' --header 'Content-Type: application/json' https://android.googleapis.com/gcm/send -d '{"registration_ids": "#{@m}", "collapse_key": "Turn", "data": { "title": "test", "sound": true,"body": "test", "badge": "1" , "content_available": 1 ,"url": ""}}') 

顯示JSON解析錯誤,你可以幫我從了這一點? Thanx提前。

+0

我剛剛嘗試過您的命令,完全如上所示,它對我來說工作得很好。你確定這是產生錯誤的線嗎? –

回答

2

首先讓我們弄清楚出了什麼問題。這是你的代碼的近似修剪爲簡潔:

ids = ["d_sample_id1","d_sample_id2"] 
puts %(curl ... -d '{"registration_ids": "#{ids}"}') 

這裏我使用的puts %()代替%x(...)只打印字符串,而不是執行它。以下是輸出:

curl ... -d '{"registration_ids": "["d_sample_id1", "d_sample_id2"]"}' 

發現問題?它在這裏:"["d_...。你已經把你的數組放在雙引號內。當JSON解析器看到第一個雙引號時,它認爲「啊,這是一個字符串的開始」。然後到達下一個雙引號,在方括號後面,並且認爲,「這裏是字符串的結尾。」但接下來的字符是字母d,在字符串之後沒有任何意義,所以解析器拋出一個錯誤並將其稱爲一天。

可能通過刪除多餘的引號來解決這個問題。但最好是這樣做,因爲這個原因:它只能在附帶。在Ruby中使用字符串插值時,Ruby在#{...}內的表達式上調用to_s。但是,這只是偶然的,當你在一串Ruby字符串上調用to_s時,你會得到有效的JSON。如果表達式是哈希或日期怎麼辦?字符串插值會使你失敗。

但即使你知道你剛剛得到了一個字符串數組,第二個原因也會導致插值失敗:你正在構建需要正確轉義的命令行參數。以此爲例:

arr = ["I can't even"] 
%(curl ... -d '#{arr}') 

發現問題?這將嘗試執行以下操作:

curl ... -d '["I can't even"]' 

發現問題?這次你的單引號不匹配。

真是個噩夢!

這讓我們的拇指兩個重要的規則:

  1. 不要建立與字符串連接/插值JSON除非你喜歡痛苦和折磨。

  2. 使用字符串連接/插值來構建命令行參數時要非常小心,除非您享受痛苦和痛苦。

好在我們不必擔心我們的JSON被正確格式化或我們的命令行參數進行正確轉義,因爲許多聰明的人比我們已經擔心這些事情,把解決右轉入紅寶石的標準庫,在令人愉快的JSON和Shellwords模塊中。所以:

require "json" 
require "shellwords" 

ids = [ "d_sample_id1", "d_sample_id2" ] 

data = { 
    registration_ids: ids, 
    collapse_key: "Turn", 
    data: { 
    title: "test", 
    sound: true, 
    body: "test", 
    badge: "1" , 
    content_available: 1, 
    url: "" 
    } 
} 

json_arg = Shellwords.escape(data.to_json) 

%x(curl \ 
    --header 'Authorization: key=keynotmentioned' \ 
    --header 'Content-Type: application/json' \ 
    "https://android.googleapis.com/gcm/send" \ 
    -d #{json_arg} 
) 

作爲獎勵,能夠建立我們的數據作爲一個Ruby的Hash使得它的方式更具可讀性,可維護性和可測試。

+0

它爲我工作,但我用逃跑寶石代替貝殼寶石作爲我的應用程序是一個較低版本的紅寶石 – Ranzit

+0

什麼版本? Shellwords不是寶石;它在標準庫中,並且從Ruby 1.8.7(2008)開始。如果你使用的東西比你早,舊版本不再收到安全補丁。 –

+0

我使用紅寶石1.8.6。 – Ranzit