2016-01-22 57 views
1

我有一種感覺,我只是看着這個錯誤,但我想通過Angular的$ http.get()方法(特別是包含逗號的參數)傳遞URL查詢參數的正確方式得到反饋。如何使用AngularJS正確發送包含逗號的網址參數?

比方說,我有以下數據,在GET請求中使用的URL參數:

var params = { 
    filter : [ 
    "My filter", 
    "My other filter", 
    "A filter, that contains, some commas" 
    ], 
    sort : [ 
    "ascending" 
    ] 
}; 

現在,我這種結構轉換的一些參數可以被送入$http.get

var urlParams = {}; 
angular.forEach(params, function(value, name) { 
    urlParams[name] = ""; 
    for (var i = 0; i < value.length; i++) { 
     urlParams[name] += value[i]; 
     if (i < value.length - 1) { 
     urlParams[name] += "," 
     } 
    } 
} 

在這一點上,urlParams看起來是這樣的:

{ 
    filter : "My filter,My other filter,A filter, that contains, some commas", 
    sort : "ascending" 
} 

現在,這不是我想要的,因爲第三個filter參數現在變成了三個單獨的參數。 (我正在使用的API不允許以任何其他方式傳遞參數的多個值:「?param = value1,value2,value3」)所以,我需要做的是URI首先對這些值進行編碼, ?所以,我想補充一個encodeURIComponent()上述程序是這樣的:

urlParams[name] += encodeURIComponent(value[i]); 

這給了我一個參數對象,看起來像這樣:

{ 
    filter : "My%20filter,My%20other%20filter,A%20filter%2C%20that%20contains%2C%20some%20commas", 
    sort : "ascending" 
} 

現在,我提出一個要求:

var config = { 
    params : urlParams 
}; 
$http.get("/foo", config).then(function(response){ 
    console.log(response); 
}); 

...這是行不通的,因爲Angular也會編碼URL參數,所以請求最終看起來像這樣:

GET "/foo?filter=My%2520filter,My%2520other%2520filter,A%2520filter%2C%20that%20contains%2C%20some%20commas&sort=ascending" 

正如你所看到的參數被編碼了兩次(%符號被編碼爲%25),這當然是行不通的。

顯然,我做錯了。但是,正確的方法是什麼?或者,我是否需要讓API開發人員接受這樣的URL參數?

GET "/foo?filter=My+filter,+with+a+comma&filter=Another+filter" 

其中多個參數值分開陳述,而不是用逗號分隔?

回答

4

在API中,沒有辦法可靠地傳遞包含逗號的值。

假設您想要將項目["one","two","three,four"]作爲列表傳遞。

  • 如果傳遞字符串作爲-是,該API將看到(正常服務器端的URL解碼後)

    one,two,three,four 
    

    這使得three,four從兩個不同的項目難以區分。

  • 如果傳遞字符串URL編碼,整個參數將是雙重編碼,和API將看到(再次,URL解碼後)

    one,two,three%2Cfour 
    

    現在的參數區分,但是這需要來自API的支持來分別對每個項目進行URL解碼。

  • 假設你傳遞了像one,two,"three,four"這樣的字符串,即引用了包含逗號的項目。該API 可以正確解碼的參數,但它需要支持更復雜的語法(引號中的字符串),而不是簡單地分裂用逗號......

...等等。底線是,沒有API的額外支持,我不認爲有任何事情可以讓客戶端欺騙它來正確解碼包含逗號的字符串。有 API開發人員可以做的許多調整,例如。

  1. 在服務器端未經轉義的列表項中接受某些轉義序列。
  2. 接受單獨URL參數中的每個項目。
  3. 通過POST接受JSON編碼的主體。

您將需要要求API開發人員執行某事

+0

感謝您幫助我認爲它通過。如果有最佳答案,我想它一定是這個,因爲那是我最終要求的 - API開發者做一些調整。 –

1

我想你不應該使用逗號作爲數組的分隔符。

我會建議使用POST(需要API變化)

  • 發送JSON數據

或使用其他字符串作爲分隔符。例如,@@@。只需將您的數組像這樣加入到字符串中即可。

array.join(',')

+0

也許在我的問題中不清楚爲什麼這是一個GET而不是POST。該請求是從RESTful API背後的資源檢索數據。這些參數告訴API如何過濾和排序數據。因此使用POST並不適合。感謝提醒我使用'加入' - 一個我需要打破的舊習慣:) –

+0

然後我猜你可以base64編碼你的參數。 – emil

0

從$ HTTP文檔

如果希望重寫請求/響應的轉換僅適用於單個請求,則提供transformRequest和/或transformResponse屬性傳遞到$ HTTP配置對象上。

請注意,如果您在配置對象上提供這些屬性,默認轉換將被覆蓋。如果您希望增加默認轉換,那麼您必須將它們包含在本地轉換數組中。

總之,你可以用你的encodeURIComponent()功能,通過在配置對象transformRequest屬性爲每個請求更換默認的或者你可以建立一個全球性的覆蓋

「轉變請求和響應」$http docs更多細節

不知道爲什麼你要如你descri發送此爲GET首先

+0

謝謝 - 這可能是做到這一點的方法。這是一個GET請求,因爲它是從REST API後面的資源檢索數據。 –

+0

其實,我認爲我需要做的是利用配置中的'paramSerializer'選項。然後,我可以在* angular完成它自己的序列化之後序列化查詢值*:https://code.angularjs.org/1.4.8/docs/api/ng/service/$http#usage –