JavaScript / jQuery의 $ .param () 역함수
다음과 같은 형태가 주어진다 :
<form>
<input name="foo" value="bar">
<input name="hello" value="hello world">
</form>
$.param( .. )
구조를 사용 하여 양식을 직렬화 할 수 있습니다 .
$.param( $('form input') )
=> foo=bar&hello=hello+world
JavaScript로 위의 문자열을 역 직렬화하고 해시를 다시 얻는 방법은 무엇입니까?
예를 들어
$.magicFunction("foo=bar&hello=hello+world")
=> {'foo' : 'bar', 'hello' : 'hello world'}
참조 : jQuery.param( obj )
.
당신은 사용해야합니다 jQuery를 BBQ 의 deparam의 기능을. 잘 테스트되고 문서화되었습니다.
이것은 내가 전에 비슷한 것을하기 위해 쓴 함수의 약간 수정 된 버전입니다.
var QueryStringToHash = function QueryStringToHash (query) {
var query_string = {};
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
pair[0] = decodeURIComponent(pair[0]);
pair[1] = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = pair[1];
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]], pair[1] ];
query_string[pair[0]] = arr;
// If third or later entry with this name
} else {
query_string[pair[0]].push(pair[1]);
}
}
return query_string;
};
이 짧은 기능적 접근은 어떻습니까?
function parseParams(str) {
return str.split('&').reduce(function (params, param) {
var paramSplit = param.split('=').map(function (value) {
return decodeURIComponent(value.replace(/\+/g, ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
예:
parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}
내 대답 :
function(query){
var setValue = function(root, path, value){
if(path.length > 1){
var dir = path.shift();
if( typeof root[dir] == 'undefined' ){
root[dir] = path[0] == '' ? [] : {};
}
arguments.callee(root[dir], path, value);
}else{
if( root instanceof Array ){
root.push(value);
}else{
root[path] = value;
}
}
};
var nvp = query.split('&');
var data = {};
for( var i = 0 ; i < nvp.length ; i++ ){
var pair = nvp[i].split('=');
var name = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
var first = path[1];
if(path[2]){
//case of 'array[level1]' || 'array[level1][level2]'
path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
}else{
//case of 'name'
path = [];
}
path.unshift(first);
setValue(data, path, value);
}
return data;
}
David Dorward의 답변을 사용하고 있으며 PHP 또는 Ruby on Rails와 같이 매개 변수를 구문 분석하는 방식으로 작동하지 않는다는 것을 깨달았습니다.
1) 변수는 다음 []
과 같이 ?choice[]=1&choice[]=12
끝나지 않고 로 끝나는 경우에만 배열 입니다.?a=1&a=2
2) 여러 매개 변수가 같은 이름으로 존재하는 경우 PHP 서버에서와 같이 후자의 매개 변수가 이전 매개 변수를 대체합니다 (Ruby on Rails는 첫 번째 것을 유지하고 후자 무시) ?a=1&b=2&a=3
David의 버전을 수정하면 다음과 같습니다.
function QueryStringToHash(query) {
if (query == '') return null;
var hash = {};
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
var k = decodeURIComponent(pair[0]);
var v = decodeURIComponent(pair[1]);
// If it is the first entry with this name
if (typeof hash[k] === "undefined") {
if (k.substr(k.length-2) != '[]') // not end with []. cannot use negative index as IE doesn't understand it
hash[k] = v;
else
hash[k.substr(0, k.length-2)] = [v];
// If subsequent entry with this name and not array
} else if (typeof hash[k] === "string") {
hash[k] = v; // replace it
// If subsequent entry with this name and is array
} else {
hash[k.substr(0, k.length-2)].push(v);
}
}
return hash;
};
상당히 철저하게 테스트되었습니다.
나는 이것이 오래된 실이라는 것을 알고 있지만 어쩌면 여전히 관련이 있습니까?
Jacky Li의 좋은 솔루션에서 영감을 얻어 배열과 객체의 임의 조합을 입력으로 처리 할 수 있도록 목표와 함께 약간의 변형을 시도했습니다. PHP가 어떻게했는지 살펴보고 "유사한"것을 얻으려고 노력했습니다. 내 코드는 다음과 같습니다.
function getargs(str){
var ret={};
function build(urlnam,urlval,obj){ // extend the return object ...
var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
while (x=rx.exec(urlnam)) idx.push(x[1]);
while(true){
k=idx.shift();
if(k.trim()=='') {// key is empty: autoincremented index
if (o.constructor.name=='Array') k=o.length; // for Array
else if (o===obj ) {k=null} // for first level property name
else {k=-1; // for Object
for(i in o) if (+i>k) k=+i;
k++;
}
}
if(idx.length) {
// set up an array if the next key (idx[0]) appears to be
// numeric or empty, otherwise set up an object:
if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[];
o=o[k]; // move on to the next level
}
else { // OK, time to store the urlval in its chosen place ...
// console.log('key',k,'val',urlval);
o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
}
}
return obj;
}
// ncnvt: is a flag that governs the conversion of
// numeric strings into numbers
var ncnvt=true,i,k,p,v,argarr=[],
ar=(str||window.location.search.substring(1)).split("&"),
l=ar.length;
for (i=0;i<l;i++) {if (ar[i]==="") continue;
p=ar[i].split("=");k=decodeURIComponent(p[0]);
v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
argarr.push([k,v]); // array: key-value-pairs of all arguments
}
for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
return ret;
}
함수가 str
-argument 없이 호출 window.location.search.slice(1)
되면 입력으로 가정 합니다.
몇 가지 예 :
['a=1&a=2', // 1
'x[y][0][z][]=1', // 2
'hello=[%22world%22]&world=hello', // 3
'a=1&a=2&&b&c=3&d=&=e&', // 4
'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc', // 5
$.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')
결과
{"a":2} // 1
{"x":{"y":[{"z":[1]}]}} // 2
{"hello":"[\"world\"]","world":"hello"} // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]} // 5
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]} // 6
{"a":["hi",2,null,[7,99],13]} // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}} // 8
Jacky Li의 솔루션은 외부 컨테이너를 a
일반 객체로 생성하는 반면
{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output
getargs()
이 레벨이 객체 (비 숫자 인덱스)인지 아니면 배열 (숫자 또는 비어 있는지)인지 여부를 판별하기 위해 임의의 레벨에 대해 첫 번째 제공된 인덱스를 확인하여 목록보기 (6 번)에 표시된대로 결과를 생성합니다.
현재 객체가 배열이면 null
빈 위치를 나타내는 데 필요한 곳에 s가 삽입됩니다. 배열은 항상 연속적으로 번호가 매겨지고 0부터 시작합니다).
이 예에서는 no. 8 빈 인덱스에 대한 "자동 증가"는 여전히 배열이 아닌 객체를 처리하지만 여전히 작동합니다.
내가 테스트 한 한, 내 대답은 허용 된 답변에 언급 된 getargs()
Chriss Roger의 훌륭한 jQuery $.deparam()
플러그인 과 거의 동일하게 작동 합니다. 가장 큰 차이점은 즉 getargs
jQuery를하지 않고 실행하고 있음을 수행 하는 동안 객체에 자동 증가를 $.deparam()
할 수 없습니다 그렇게 :
JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);
결과
{"3":["7","99"],"x":"hi","undefined":"13"}
에서 $.deparam()
인덱스 []
int로서 해석됩니다 undefined
대신 autoincremented 숫자 인덱스의.
새로운 jQuery 함수를 생성하는 방법은 다음과 같습니다.
jQuery.unparam = function (value) {
var
// Object that holds names => values.
params = {},
// Get query string pieces (separated by &)
pieces = value.split('&'),
// Temporary variables used in loop.
pair, i, l;
// Loop through query string pieces and assign params.
for (i = 0, l = pieces.length; i < l; i++) {
pair = pieces[i].split('=', 2);
// Repeated parameters with the same name are overwritten. Parameters
// with no value get set to boolean true.
params[decodeURIComponent(pair[0])] = (pair.length == 2 ?
decodeURIComponent(pair[1].replace(/\+/g, ' ')) : true);
}
return params;
};
그 덕분에 http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
아주 쉬운 : D
function params_unserialize(p){
var ret = {},
seg = p.replace(/^\?/,'').split('&'),
len = seg.length, i = 0, s;
for (;i<len;i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;}
서버 측 JScript ASP Classic 페이지 ( demo ) 에서 사용하는 JavaScript 구현은 다음과 같습니다 .
// Transforms a query string in the form x[y][0][z][]=1 into {x:{y:[{z:[1]}]}}
function parseJQueryParams(p) {
var params = {};
var pairs = p.split('&');
for (var i=0; i<pairs.length; i++) {
var pair = pairs[i].split('=');
var indices = [];
var name = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]);
var name = name.replace(/\[([^\]]*)\]/g,
function(k, idx) { indices.push(idx); return ""; });
indices.unshift(name);
var o = params;
for (var j=0; j<indices.length-1; j++) {
var idx = indices[j];
var nextIdx = indices[j+1];
if (!o[idx]) {
if ((nextIdx == "") || (/^[0-9]+$/.test(nextIdx)))
o[idx] = [];
else
o[idx] = {};
}
o = o[idx];
}
idx = indices[indices.length-1];
if (idx == "") {
o.push(value);
}
else {
o[idx] = value;
}
}
return params;
}
이것을 사용하십시오 :
// convert query string to json object
var queryString = "cat=3&sort=1&page=1";
queryString
.split("&")
.forEach((item) => {
const prop = item.split("=");
filter[prop[0]] = prop[1];
});
console.log(queryString);
CSS-Tricks ( Nicholas Ortenzio의 원본 출처) 에는 아름다운 원 라이너가 있습니다 .
function getQueryParameters(str) {
return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}
정말 영리한 부분은 익명 함수의 this
객체를 사용하여 문자열의 각 쿼리에 키 / 값 쌍을 추가하는 방법입니다. 즉, 개선의 여지가 있습니다. 다음과 같이 변경하여 아래에서 약간 수정했습니다.
빈 문자열 및 문자열이 아닌 입력 처리가 추가되었습니다.
처리 된 URI 인코딩 문자열 (
%40
->@
등)document.location.search
입력이 비어있을 때 의 기본 사용을 제거했습니다 .이름을 변경하고 더 읽기 쉽게 만들었으며 주석을 추가했습니다.
function deparam(str) {
// Uses an empty 'this' to build up the results internally
function splitQuery(query) {
query = query.split('=').map(decodeURIComponent);
this[query[0]] = query[1];
return this;
}
// Catch bad input
if (!str || !(typeof str === 'string' || str instanceof String))
return {};
// Split the string, run splitQuery on each piece, and return 'this'
var queries = str.replace(/(^\?)/,'').split('&');
return queries.map(splitQuery.bind({}))[0];
}
이것은 Coffeescript의 내 버전입니다. 같은 URL에서도 작동합니다.http://localhost:4567/index.html?hello=[%22world%22]&world=hello#/home
getQueryString: (url)->
return null if typeof url isnt 'string' or url.indexOf("http") is -1
split = url.split "?"
return null if split.length < 2
path = split[1]
hash_pos = path.indexOf "#"
path = path[0...hash_pos] if hash_pos isnt -1
data = path.split "&"
ret = {}
for d in data
[name, val] = d.split "="
name = decodeURIComponent name
val = decodeURIComponent val
try
ret[name] = JSON.parse val
catch error
ret[name] = val
return ret
.Net 함수처럼 동작하는이 솔루션을 생각해 냈습니다 HttpUtility.ParseQueryString
.
결과적으로 쿼리 문자열 매개 변수는 속성에 값 목록으로 저장되므로 .Net에서 qsObj["param"]
호출하는 것과 같습니다 GetValues("param")
.
나는 그것을 좋아하면 좋겠. JQuery가 필요하지 않습니다.
var parseQueryString = function (querystring) {
var qsObj = new Object();
if (querystring) {
var parts = querystring.replace(/\?/, "").split("&");
var up = function (k, v) {
var a = qsObj[k];
if (typeof a == "undefined") {
qsObj[k] = [v];
}
else if (a instanceof Array) {
a.push(v);
}
};
for (var i in parts) {
var part = parts[i];
var kv = part.split('=');
if (kv.length == 1) {
var v = decodeURIComponent(kv[0] || "");
up(null, v);
}
else if (kv.length > 1) {
var k = decodeURIComponent(kv[0] || "");
var v = decodeURIComponent(kv[1] || "");
up(k, v);
}
}
}
return qsObj;
};
사용 방법은 다음과 같습니다.
var qsObj = parseQueryString("a=1&a=2&&b&c=3&d=&=e&");
콘솔에서 결과를 미리 보려면 다음을 입력하십시오.
JSON.stringify(qsObj)
산출:
"{"a":["1","2"],"null":["","b",""],"c":["3"],"d":[""],"":["e"]}"
다음은 GET 요청에서 매개 변수를 빠르게 가져 오려는 경우 간단하고 간결한 것입니다.
function httpGet() {
var a={},b,i,q=location.search.replace(/^\?/,"").split(/\&/);
for(i in q) if(q[i]) {b=q[i].split("=");if(b[0]) a[b[0]]=
decodeURIComponent(b[1]).replace(/\+/g," ");} return a;
}
그것은 변환
something?aa=1&bb=2&cc=3
같은 물건으로
{aa:1,bb:2,cc:3}
배열 또는 객체의 직렬화 된 표현을 만듭니다 (AJAX 요청의 URL 쿼리 문자열로 사용할 수 있음).
<button id='param'>GET</button>
<div id="show"></div>
<script>
$('#param').click(function () {
var personObj = new Object();
personObj.firstname = "vishal"
personObj.lastname = "pambhar";
document.getElementById('show').innerHTML=$.param(`personObj`));
});
</script>
output:firstname=vishal&lastname=pambhar
이것은 정말로 오래된 질문이지만, 내가 올 때-다른 사람들 이이 게시물에 올 수 있으며,이 테마를 약간 새로 고치고 싶습니다. 현재 맞춤 솔루션을 만들 필요가 없습니다 . URLSearchParams 인터페이스가 있습니다.
var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);
//Iterate the search parameters.
for (let p of searchParams) {
console.log(p);
}
내가 아는 유일한 제한 사항-이 기능은 IE / Edge에서 지원되지 않습니다.
대답은 약간의 jQuery 우아함을 사용할 수 있습니다 .
(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
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;
}
return params;
};
})(jQuery);
https://gist.github.com/956897 에서 포크
jQuery 자체 의 함수 .serializeArray()
( Link )를 사용할 수 있습니다 . 이 함수는 키-값 쌍의 배열을 반환합니다. 결과 예 :
[
{ name: "id", value: "1" },
{ name: "version", value: "100" }
]
참고 URL : https://stackoverflow.com/questions/1131630/the-param-inverse-function-in-javascript-jquery
'Programing' 카테고리의 다른 글
BackgroundWorker가 취소 될 때까지 기다리는 방법은 무엇입니까? (0) | 2020.07.16 |
---|---|
Visual Studio에서“…를 제외한 모든 경고는 오류로 처리하십시오.” (0) | 2020.07.16 |
TFS 코드 검토-주석에 대한 응답으로 업데이트 된 파일 표시 (0) | 2020.07.16 |
node.js와 io.js의 차이점은 무엇입니까? (0) | 2020.07.16 |
과도 및 휘발성 수정 자란 무엇입니까? (0) | 2020.07.16 |