Tôi có một chuỗi như thế này:
abc=foo&def=%5Basf%5D&xyz=5
Làm cách nào tôi có thể chuyển đổi nó thành một đối tượng JavaScript như thế này?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Tôi có một chuỗi như thế này:
abc=foo&def=%5Basf%5D&xyz=5
Làm cách nào tôi có thể chuyển đổi nó thành một đối tượng JavaScript như thế này?
{
abc: 'foo',
def: '[asf]',
xyz: 5
}
Câu trả lời:
Chỉnh sửa này cải thiện và giải thích câu trả lời dựa trên các ý kiến.
var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
Thí dụ
Phân tích abc=foo&def=%5Basf%5D&xyz=5
theo năm bước:
abc=foo","def=[asf]","xyz=5
abc":"foo","def":"[asf]","xyz":"5
{"abc":"foo","def":"[asf]","xyz":"5"}
JSON hợp pháp.
Một giải pháp cải tiến cho phép có nhiều ký tự hơn trong chuỗi tìm kiếm. Nó sử dụng chức năng phục hồi để giải mã URI:
var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })
Thí dụ
search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";
cho
Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}
Một lớp lót:
JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')
JSON.parse('{"' + decodeURI(location.search.substring(1).replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}')
Bắt đầu ES6 trở đi, Javascript cung cấp một số cấu trúc để tạo ra giải pháp hiệu quả cho vấn đề này.
Điều này bao gồm sử dụng URLSearchParams và iterators
let params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
params.get("abc"); // "foo"
Nếu trường hợp sử dụng của bạn yêu cầu bạn thực sự chuyển đổi nó thành đối tượng, bạn có thể thực hiện chức năng sau:
function paramsToObject(entries) {
let result = {}
for(let entry of entries) { // each 'entry' is a [key, value] tupple
const [key, value] = entry;
result[key] = value;
}
return result;
}
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const entries = urlParams.entries(); //returns an iterator of decoded [key,value] tuples
const params = paramsToObject(entries); //{abc:"foo",def:"[asf]",xyz:"5"}
Chúng ta có thể sử dụng Object.fromEntries (hiện đang ở giai đoạn 4), thay thế paramsToObject
bằng Object.fromEntries(entries)
.
Các cặp giá trị được lặp lại là các cặp tên-giá trị danh sách với khóa là tên và giá trị là giá trị.
Vì URLParams
, trả về một đối tượng có thể lặp lại , sử dụng toán tử trải rộng thay vì gọi .entries
cũng sẽ mang lại các mục nhập theo thông số kỹ thuật của nó:
const urlParams = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5');
const params = Object.fromEntries(urlParams); // {abc: "foo", def: "[asf]", xyz: "5"}
Lưu ý: Tất cả các giá trị được tự động chuỗi theo thông số URLSearchParams
Như @siipe đã chỉ ra, các chuỗi chứa nhiều giá trị khóa giống nhau sẽ được ép buộc vào giá trị khả dụng cuối cùng: foo=first_value&foo=second_value
về bản chất sẽ trở thành : {foo: "second_value"}
.
Theo câu trả lời này: https://stackoverflow.com/a/1746566/1194694 không có thông số nào để quyết định làm gì với nó và mỗi khung có thể hành xử khác nhau.
Một trường hợp sử dụng phổ biến sẽ là nối hai giá trị giống nhau thành một mảng, biến đối tượng đầu ra thành:
{foo: ["first_value", "second_value"]}
Điều này có thể đạt được với mã sau đây:
const groupParamsByKey = (params) => [...params.entries()].reduce((acc, tuple) => {
// getting the key and value from each tuple
const [key, val] = tuple;
if(acc.hasOwnProperty(key)) {
// if the current key is already an array, we'll add the value to it
if(Array.isArray(acc[key])) {
acc[key] = [...acc[key], val]
} else {
// if it's not an array, but contains a value, we'll convert it into an array
// and add the current value to it
acc[key] = [acc[key], val];
}
} else {
// plain assignment if no special case is present
acc[key] = val;
}
return acc;
}, {});
const params = new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5&def=dude');
const output = groupParamsByKey(params) // {abc: "foo", def: ["[asf]", "dude"], xyz: 5}
search string
trình phân tích cú pháp - đó là những gì nó được thiết kế để làm, bất kể nó có liên quan đến một URL
Object.fromEntries
không hoạt động cho các phím lặp đi lặp lại. Nếu chúng ta cố gắng làm một cái gì đó như ?foo=bar1&foo=bar2
, chúng ta sẽ chỉ nhận được { foo: 'bar2' }
. Ví dụ, đối tượng yêu cầu Node.js phân tích cú pháp dưới dạng{ foo: ['bar1', 'bar2'] }
let temp={};Object.keys(params).map(key=>{temp[key]=urlParams.getAll(key)})
ES6 một lớp lót. Sạch sẽ và đơn giản.
Object.fromEntries(new URLSearchParams(location.search));
Đối với trường hợp cụ thể của bạn, nó sẽ là:
console.log(
Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'))
);
"http://place.com?foo=bar&hello=%40world&showThing"
sản xuất{ hello: "@world", http://place.com?foo: "bar", showThing: "" }
?someValue=false
trở thành{ someValue: "false" }
?foo=bar1&foo=bar2
, chúng ta sẽ chỉ nhận được { foo: 'bar2' }
. Đối tượng yêu cầu Node.js phân tích cú pháp dưới dạng{ foo: ['bar1', 'bar2'] }
location.search
Tách vào &
để có được cặp tên / giá trị, sau đó tách từng cặp trên =
. Đây là một ví dụ:
var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
var p = curr.split("=");
prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
return prev;
}, {});
Một cách tiếp cận khác, sử dụng các biểu thức chính quy:
var obj = {};
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
obj[decodeURIComponent(key)] = decodeURIComponent(value);
});
Điều này được điều chỉnh từ "Tìm kiếm và không thay thế" của John Resig .
Một giải pháp ngắn gọn:
location.search
.slice(1)
.split('&')
.map(p => p.split('='))
.reduce((obj, pair) => {
const [key, value] = pair.map(decodeURIComponent);
return ({ ...obj, [key]: value })
}, {});
Các giải pháp đề xuất tôi tìm thấy cho đến nay không bao gồm các kịch bản phức tạp hơn.
Tôi cần phải chuyển đổi một chuỗi truy vấn như
https://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields%5B%5D=name&fields%5B%5D=default_goal_name
vào một đối tượng như:
{
"Target": "Offer",
"Method": "findAll",
"fields": [
"id",
"name",
"default_goal_name"
],
"filters": {
"has_goals_enabled": {
"TRUE": "1"
},
"status": "active"
}
}
HOẶC LÀ:
https://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&fields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Stat.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999
VÀO:
{
"Target": "Report",
"Method": "getStats",
"fields": [
"Offer.name",
"Advertiser.company",
"Stat.clicks",
"Stat.conversions",
"Stat.cpa",
"Stat.payout",
"Stat.date",
"Stat.offer_id",
"Affiliate.company"
],
"groups": [
"Stat.offer_id",
"Stat.date"
],
"limit": "9999",
"filters": {
"Stat.affiliate_id": {
"conditional": "EQUAL_TO",
"values": "1831"
}
}
}
MÃ:
var getParamsAsObject = function (query) {
query = query.substring(query.indexOf('?') + 1);
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g;
var decode = function (str) {
return decodeURIComponent(str.replace(decodeRE, " "));
};
var params = {}, e;
while (e = re.exec(query)) {
var k = decode(e[1]), v = decode(e[2]);
if (k.substring(k.length - 2) === '[]') {
k = k.substring(0, k.length - 2);
(params[k] || (params[k] = [])).push(v);
}
else params[k] = v;
}
var assign = function (obj, keyPath, value) {
var lastKeyIndex = keyPath.length - 1;
for (var i = 0; i < lastKeyIndex; ++i) {
var key = keyPath[i];
if (!(key in obj))
obj[key] = {}
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}
for (var prop in params) {
var structure = prop.split('[');
if (structure.length > 1) {
var levels = [];
structure.forEach(function (item, i) {
var key = item.replace(/[?[\]\\ ]/g, '');
levels.push(key);
});
assign(params, levels, params[prop]);
delete(params[prop]);
}
}
return params;
};
obj=encodeURIComponent(JSON.stringify({what:{ever:','},i:['like']}))
.
Đây là phiên bản đơn giản, rõ ràng bạn sẽ muốn thêm một số kiểm tra lỗi:
var obj = {};
var pairs = queryString.split('&');
for(i in pairs){
var split = pairs[i].split('=');
obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
}
JSON.parse('{"' + decodeURIComponent(query.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}'));
làm việc cho tôi
name[]=test1&name[]=test2
và nó sẽ dẫn đếnname[]=test2
Tôi đã tìm thấy $ .String.deparam là giải pháp được xây dựng hoàn chỉnh nhất (có thể thực hiện các đối tượng lồng nhau, v.v.). Kiểm tra các tài liệu .
Đối với trường hợp cụ thể của bạn:
Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'));
Đối với trường hợp chung hơn khi ai đó muốn phân tích các tham số truy vấn đến một đối tượng:
Object.fromEntries(new URLSearchParams(location.search));
Nếu bạn không thể sử dụng Object.fromEntries, điều này cũng sẽ hoạt động:
Array.from(new URLSearchParams(window.location.search)).reduce((o, i) => ({ ...o, [i[0]]: i[1] }), {});
[...new URLSearchParams(window.location.search)].reduce((o, i) => ({ ...o, [i[0]]: i[1] }), {});
"http://place.com?foo=bar&hello=%40world&showThing
sản xuất { hello: "@world", http://place.com?foo: "bar", showThing: "" }
. Hãy thử thêmstr.split("?").pop()
Một giải pháp khác dựa trên tiêu chuẩn mới nhất của URLSearchParams ( https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams )
function getQueryParamsObject() {
const searchParams = new URLSearchParams(location.search.slice(1));
return searchParams
? _.fromPairs(Array.from(searchParams.entries()))
: {};
}
Xin lưu ý rằng giải pháp này được sử dụng
Array.from ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from )
và _.fromPairs ( https://lodash.com/docs#fromPairs ) của lodash vì mục đích đơn giản.
Thật dễ dàng để tạo ra một giải pháp tương thích hơn vì bạn có quyền truy cập vào trình tìm kiếm searchParams.entries () .
Tôi đã có cùng một vấn đề, đã thử các giải pháp ở đây, nhưng không có giải pháp nào thực sự hiệu quả, vì tôi có các mảng trong các tham số URL, như thế này:
?param[]=5¶m[]=8&othr_param=abc¶m[]=string
Vì vậy, tôi đã kết thúc việc viết hàm JS của riêng mình, điều này tạo ra một mảng nằm ngoài param trong URI:
/**
* Creates an object from URL encoded data
*/
var createObjFromURI = function() {
var uri = decodeURI(location.search.substr(1));
var chunks = uri.split('&');
var params = Object();
for (var i=0; i < chunks.length ; i++) {
var chunk = chunks[i].split('=');
if(chunk[0].search("\\[\\]") !== -1) {
if( typeof params[chunk[0]] === 'undefined' ) {
params[chunk[0]] = [chunk[1]];
} else {
params[chunk[0]].push(chunk[1]);
}
} else {
params[chunk[0]] = chunk[1];
}
}
return params;
}
if(chunk[0].search("\\[\\]") !== -1) {
đóchunk[0]=chunk[0].replace(/\[\]$/,'');
const
thay var
vì bởi vì ai đó có thể làm createObjFromURI = 'some text'
và sau đó họ sẽ làm rối mã. nếu bạn sử dụng const
thì ai đó đang chạy createObjFromURI = 'some text'
sẽ gây ra lỗi không thể gán giá trị cho biến không đổi.
Sử dụng ES6, API URL và API URLSearchParams.
function objectifyQueryString(url) {
let _url = new URL(url);
let _params = new URLSearchParams(_url.search);
let query = Array.from(_params.keys()).reduce((sum, value)=>{
return Object.assign({[value]: _params.get(value)}, sum);
}, {});
return query;
}
ES6 một lớp lót (nếu chúng ta có thể gọi nó theo cách nhìn thấy đường dài)
[...new URLSearchParams(location.search).entries()].reduce((prev, [key,val]) => {prev[key] = val; return prev}, {})
cur
cho một số rõ ràng thêm. .reduce((prev, [key, val]) => {prev[key] = val})
Khá dễ dàng khi sử dụng URLSearchParams
API Web JavaScript,
var paramsString = "q=forum&topic=api";
//returns an iterator object
var searchParams = new URLSearchParams(paramsString);
//Usage
for (let p of searchParams) {
console.log(p);
}
//Get the query strings
console.log(searchParams.toString());
//You can also pass in objects
var paramsObject = {q:"forum",topic:"api"}
//returns an iterator object
var searchParams = new URLSearchParams(paramsObject);
//Usage
for (let p of searchParams) {
console.log(p);
}
//Get the query strings
console.log(searchParams.toString());
LƯU Ý : Không được hỗ trợ trong IE
Đối với Node JS, bạn có thể sử dụng API Node JS querystring
:
const querystring = require('querystring');
querystring.parse('abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar');
// returns the object
Tài liệu: https://nodejs.org/api/queryopes.html
Không có giải pháp bản địa mà tôi biết. Dojo có một phương thức unerialization tích hợp nếu bạn sử dụng khung đó một cách tình cờ.
Nếu không, bạn có thể tự thực hiện nó một cách đơn giản:
function unserialize(str) {
str = decodeURIComponent(str);
var chunks = str.split('&'),
obj = {};
for(var c=0; c < chunks.length; c++) {
var split = chunks[c].split('=', 2);
obj[split[0]] = split[1];
}
return obj;
}
chỉnh sửa: đã thêm decodeURIComponent ()
Có một thư viện gọn nhẹ có tên YouAreI.js đã được thử nghiệm và làm cho việc này thực sự dễ dàng.
YouAreI = require('YouAreI')
uri = new YouAreI('http://user:pass@www.example.com:3000/a/b/c?d=dad&e=1&f=12.3#fragment');
uri.query_get() => { d: 'dad', e: '1', f: '12.3' }
Một trong những cách đơn giản nhất để thực hiện việc này bằng giao diện URLSearchParam.
Dưới đây là đoạn mã làm việc:
let paramObj={},
querystring=window.location.search,
searchParams = new URLSearchParams(querystring);
//*** :loop to add key and values to the param object.
searchParams.forEach(function(value, key) {
paramObj[key] = value;
});
Đây có vẻ là giải pháp tốt nhất vì nó cần xem xét nhiều tham số cùng tên.
function paramsToJSON(str) {
var pairs = str.split('&');
var result = {};
pairs.forEach(function(pair) {
pair = pair.split('=');
var name = pair[0]
var value = pair[1]
if( name.length )
if (result[name] !== undefined) {
if (!result[name].push) {
result[name] = [result[name]];
}
result[name].push(value || '');
} else {
result[name] = value || '';
}
});
return( result );
}
<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
paramsToJSON("x=1&x=2&x=3&y=blah");
console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON
Sau đó tôi cũng quyết định chuyển đổi nó thành một plugin jQuery ...
$.fn.serializeURLParams = function() {
var result = {};
if( !this.is("a") || this.attr("href").indexOf("?") == -1 )
return( result );
var pairs = this.attr("href").split("?")[1].split('&');
pairs.forEach(function(pair) {
pair = pair.split('=');
var name = decodeURI(pair[0])
var value = decodeURI(pair[1])
if( name.length )
if (result[name] !== undefined) {
if (!result[name].push) {
result[name] = [result[name]];
}
result[name].push(value || '');
} else {
result[name] = value || '';
}
});
return( result )
}
<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
$("a").serializeURLParams();
console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON
Bây giờ, người đầu tiên sẽ chỉ chấp nhận các tham số nhưng plugin jQuery sẽ lấy toàn bộ url và trả về các tham số được tuần tự hóa.
Đây là một cái tôi sử dụng:
var params = {};
window.location.search.substring(1).split('&').forEach(function(pair) {
pair = pair.split('=');
if (pair[1] !== undefined) {
var key = decodeURIComponent(pair[0]),
val = decodeURIComponent(pair[1]),
val = val ? val.replace(/\++/g,' ').trim() : '';
if (key.length === 0) {
return;
}
if (params[key] === undefined) {
params[key] = val;
}
else {
if ("function" !== typeof params[key].push) {
params[key] = [params[key]];
}
params[key].push(val);
}
}
});
console.log(params);
Sử dụng cơ bản, ví dụ.
?a=aa&b=bb
Object {a: "aa", b: "bb"}
Thông số trùng lặp, ví dụ.
?a=aa&b=bb&c=cc&c=potato
Object {a: "aa", b: "bb", c: ["cc","potato"]}
Thiếu chìa khóa, ví dụ.
?a=aa&b=bb&=cc
Object {a: "aa", b: "bb"}
Thiếu giá trị, ví dụ.
?a=aa&b=bb&c
Object {a: "aa", b: "bb"}
Các giải pháp JSON / regex ở trên đưa ra lỗi cú pháp trên url lập dị này:
?a=aa&b=bb&c=&=dd&e
Object {a: "aa", b: "bb", c: ""}
Đây là phiên bản nhanh và bẩn của tôi, về cơ bản, nó phân tách các tham số URL được phân tách bằng '&' thành các phần tử mảng và sau đó lặp lại qua mảng đó thêm các cặp khóa / giá trị được phân tách bằng '=' vào một đối tượng. Tôi đang sử dụng decodeURIComponent () để dịch các ký tự được mã hóa thành các chuỗi tương đương bình thường của chúng (vì vậy% 20 trở thành khoảng trắng,% 26 trở thành '&', v.v.):
function deparam(paramStr) {
let paramArr = paramStr.split('&');
let paramObj = {};
paramArr.forEach(e=>{
let param = e.split('=');
paramObj[param[0]] = decodeURIComponent(param[1]);
});
return paramObj;
}
thí dụ:
deparam('abc=foo&def=%5Basf%5D&xyz=5')
trả lại
{
abc: "foo"
def:"[asf]"
xyz :"5"
}
Vấn đề duy nhất là xyz là một chuỗi chứ không phải là một số (do sử dụng decodeURIComponent ()), nhưng ngoài ra nó không phải là điểm khởi đầu tồi.
//under ES6
const getUrlParamAsObject = (url = window.location.href) => {
let searchParams = url.split('?')[1];
const result = {};
//in case the queryString is empty
if (searchParams!==undefined) {
const paramParts = searchParams.split('&');
for(let part of paramParts) {
let paramValuePair = part.split('=');
//exclude the case when the param has no value
if(paramValuePair.length===2) {
result[paramValuePair[0]] = decodeURIComponent(paramValuePair[1]);
}
}
}
return result;
}
Babel
sự giúp đỡ của bạn, bạn có thể làm tốt điều đó trong môi trường khác
Sử dụng phpjs
function parse_str(str, array) {
// discuss at: http://phpjs.org/functions/parse_str/
// original by: Cagri Ekin
// improved by: Michael White (http://getsprink.com)
// improved by: Jack
// improved by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Onno Marsman
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: stag019
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: MIO_KODUKI (http://mio-koduki.blogspot.com/)
// reimplemented by: stag019
// input by: Dreamer
// input by: Zaide (http://zaidesthings.com/)
// input by: David Pesta (http://davidpesta.com/)
// input by: jeicquest
// note: When no argument is specified, will put variables in global scope.
// note: When a particular argument has been passed, and the returned value is different parse_str of PHP. For example, a=b=c&d====c
// test: skip
// example 1: var arr = {};
// example 1: parse_str('first=foo&second=bar', arr);
// example 1: $result = arr
// returns 1: { first: 'foo', second: 'bar' }
// example 2: var arr = {};
// example 2: parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);
// example 2: $result = arr
// returns 2: { str_a: "Jack and Jill didn't see the well." }
// example 3: var abc = {3:'a'};
// example 3: parse_str('abc[a][b]["c"]=def&abc[q]=t+5');
// returns 3: {"3":"a","a":{"b":{"c":"def"}},"q":"t 5"}
var strArr = String(str)
.replace(/^&/, '')
.replace(/&$/, '')
.split('&'),
sal = strArr.length,
i, j, ct, p, lastObj, obj, lastIter, undef, chr, tmp, key, value,
postLeftBracketPos, keys, keysLen,
fixStr = function(str) {
return decodeURIComponent(str.replace(/\+/g, '%20'));
};
if (!array) {
array = this.window;
}
for (i = 0; i < sal; i++) {
tmp = strArr[i].split('=');
key = fixStr(tmp[0]);
value = (tmp.length < 2) ? '' : fixStr(tmp[1]);
while (key.charAt(0) === ' ') {
key = key.slice(1);
}
if (key.indexOf('\x00') > -1) {
key = key.slice(0, key.indexOf('\x00'));
}
if (key && key.charAt(0) !== '[') {
keys = [];
postLeftBracketPos = 0;
for (j = 0; j < key.length; j++) {
if (key.charAt(j) === '[' && !postLeftBracketPos) {
postLeftBracketPos = j + 1;
} else if (key.charAt(j) === ']') {
if (postLeftBracketPos) {
if (!keys.length) {
keys.push(key.slice(0, postLeftBracketPos - 1));
}
keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos));
postLeftBracketPos = 0;
if (key.charAt(j + 1) !== '[') {
break;
}
}
}
}
if (!keys.length) {
keys = [key];
}
for (j = 0; j < keys[0].length; j++) {
chr = keys[0].charAt(j);
if (chr === ' ' || chr === '.' || chr === '[') {
keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
}
if (chr === '[') {
break;
}
}
obj = array;
for (j = 0, keysLen = keys.length; j < keysLen; j++) {
key = keys[j].replace(/^['"]/, '')
.replace(/['"]$/, '');
lastIter = j !== keys.length - 1;
lastObj = obj;
if ((key !== '' && key !== ' ') || j === 0) {
if (obj[key] === undef) {
obj[key] = {};
}
obj = obj[key];
} else { // To insert new dimension
ct = -1;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
if (+p > ct && p.match(/^\d+$/g)) {
ct = +p;
}
}
}
key = ct + 1;
}
}
lastObj[key] = value;
}
}
}
Dựa trên câu trả lời của Mike Causer Tôi đã thực hiện chức năng này để xem xét nhiều tham số có cùng khóa ( foo=bar&foo=baz
) và các tham số được phân tách bằng dấu phẩy ( foo=bar,baz,bin
). Nó cũng cho phép bạn tìm kiếm một khóa truy vấn nhất định.
function getQueryParams(queryKey) {
var queryString = window.location.search;
var query = {};
var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1] || '');
// Se possui uma vírgula no valor, converter em um array
value = (value.indexOf(',') === -1 ? value : value.split(','));
// Se a key já existe, tratar ela como um array
if (query[key]) {
if (query[key].constructor === Array) {
// Array.concat() faz merge se o valor inserido for um array
query[key] = query[key].concat(value);
} else {
// Se não for um array, criar um array contendo o valor anterior e o novo valor
query[key] = [query[key], value];
}
} else {
query[key] = value;
}
}
if (typeof queryKey === 'undefined') {
return query;
} else {
return query[queryKey];
}
}
Ví dụ đầu vào:
foo.html?foo=bar&foo=baz&foo=bez,boz,buz&bar=1,2,3
Ví dụ đầu ra
{
foo: ["bar","baz","bez","boz","buz"],
bar: ["1","2","3"]
}
Nếu bạn đang sử dụng URI.js, bạn có thể sử dụng:
https://medialize.github.io/URI.js/docs.html#static-parseQuery
var result = URI.parseQuery("?foo=bar&hello=world&hello=mars&bam=&yup");
result === {
foo: "bar",
hello: ["world", "mars"],
bam: "",
yup: null
};
console.log(decodeURI('abc=foo&def=%5Basf%5D&xyz=5')
.split('&')
.reduce((result, current) => {
const [key, value] = current.split('=');
result[key] = value;
return result
}, {}))
FIRST U CẦN THIẾT XÁC ĐỊNH NHỮNG GÌ NHẬN ĐƯỢC:
function getVar()
{
this.length = 0;
this.keys = [];
this.push = function(key, value)
{
if(key=="") key = this.length++;
this[key] = value;
this.keys.push(key);
return this[key];
}
}
Hơn chỉ đọc:
function urlElement()
{
var thisPrototype = window.location;
for(var prototypeI in thisPrototype) this[prototypeI] = thisPrototype[prototypeI];
this.Variables = new getVar();
if(!this.search) return this;
var variables = this.search.replace(/\?/g,'').split('&');
for(var varI=0; varI<variables.length; varI++)
{
var nameval = variables[varI].split('=');
var name = nameval[0].replace(/\]/g,'').split('[');
var pVariable = this.Variables;
for(var nameI=0;nameI<name.length;nameI++)
{
if(name.length-1==nameI) pVariable.push(name[nameI],nameval[1]);
else var pVariable = (typeof pVariable[name[nameI]] != 'object')? pVariable.push(name[nameI],new getVar()) : pVariable[name[nameI]];
}
}
}
và sử dụng như:
var mlocation = new urlElement();
mlocation = mlocation.Variables;
for(var key=0;key<mlocation.keys.length;key++)
{
console.log(key);
console.log(mlocation[mlocation.keys[key]];
}
Tôi cũng cần phải xử lý +
trong phần truy vấn của URL ( decodeURIComponent không ), vì vậy tôi đã điều chỉnh mã của Wolfgang để trở thành:
var search = location.search.substring(1);
search = search?JSON.parse('{"' + search.replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
function(key, value) { return key===""?value:decodeURIComponent(value)}):{};
Trong trường hợp của tôi, tôi đang sử dụng jQuery để lấy các tham số biểu mẫu sẵn sàng URL, sau đó mẹo này để xây dựng một đối tượng từ đó và sau đó tôi có thể dễ dàng cập nhật các tham số trên đối tượng và xây dựng lại URL truy vấn, ví dụ:
var objForm = JSON.parse('{"' + $myForm.serialize().replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
function(key, value) { return key===""?value:decodeURIComponent(value)});
objForm.anyParam += stringToAddToTheParam;
var serializedForm = $.param(objForm);
Tôi làm theo cách này:
const uri = new URL('https://example.org/?myvar1=longValue&myvar2=value')
const result = {}
for (let p of uri.searchParams) {
result[p[0]] = p[1]
}
Nếu bạn cần đệ quy, bạn có thể sử dụng thư viện js-extension-ling nhỏ .
npm i js-extension-ling
const jsx = require("js-extension-ling");
console.log(jsx.queryStringToObject("a=1"));
console.log(jsx.queryStringToObject("a=1&a=3"));
console.log(jsx.queryStringToObject("a[]=1"));
console.log(jsx.queryStringToObject("a[]=1&a[]=pomme"));
console.log(jsx.queryStringToObject("a[0]=one&a[1]=five"));
console.log(jsx.queryStringToObject("http://blabla?foo=bar&number=1234"));
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry"));
console.log(jsx.queryStringToObject("a[fruits][red][]=strawberry&a[1]=five&a[fruits][red][]=cherry&a[fruits][yellow][]=lemon&a[fruits][yellow][688]=banana"));
Điều này sẽ tạo ra một cái gì đó như thế này:
{ a: '1' }
{ a: '3' }
{ a: { '0': '1' } }
{ a: { '0': '1', '1': 'pomme' } }
{ a: { '0': 'one', '1': 'five' } }
{ foo: 'bar', number: '1234' }
{
a: { fruits: { red: { '0': 'strawberry' } } }
}
{
a: {
'1': 'five',
fruits: {
red: { '0': 'strawberry', '1': 'cherry' },
yellow: { '0': 'lemon', '688': 'banana' }
}
}
}
Lưu ý: nó dựa trên hàm parse_str của locutus ( https://locutus.io/php/strings/parse_str/ ).