재미있는 것: 검색 문자열에서 그룹과 대상을 표시합니다

15854 단어 phpjavascriptnode
질문: URL 쿼리 문자열에서 배열과 객체를 나타내는 올바른 방법은 무엇입니까?

What do you think is the *correct* way to pass array query parameters in a URL?

— jukai (樹海) (@theshalvah)


이것은 추문에서 문제의 확장판입니다: 만약 당신이 이 물체를 가지고 있다면...
{
  dog: { // an object
    name: 'John',
    age: 12
  },
  user_ids: [1, 3] // an array 
}
...검색 문자열의 정확한 형식은 무엇입니까?
정답:'정답'의 방법은 없다.이것은 어느 정도에 당신의 운행 환경 (언어, 프레임워크, 플랫폼) 에 달려 있습니다.몇몇 유행하는 환경이 어떻게 처리되는지 봅시다.

PHP
PHP에서는 http_build_query를 사용하여 인코딩할 수 있습니다.
$params = [
  'dog' => ['name' => 'John', 'age' => 12], 
  'user_ids' => [1, 3]
];
urldecode(http_build_query($params));
// Gives you: "dog[name]=John&dog[age]=12&user_ids[0]=1&user_ids[1]=3"
(주의:저는 urldecode-ing을 하고 있기 때문에 출력은 쉽게 읽을 수 있습니다.)
따라서 PHP는 네모난 괄호 안에 중첩된 키를 사용하여 배열/객체를 벤드펴기합니다.또한 다차원 배열/객체도 지원됩니다.
$params = [
  'dogs' => [
    ['name' => 'John', 'age' => 12], 
    ['name' => 'Kim', 'age' => 13], 
  ]
];
urldecode(http_build_query($params));
// Gives you: "dogs[0][name]=John&dogs[0][age]=12&dogs[1][name]=Kim&dogs[1][age]=13"
디코딩은요?parse_str를 사용하여 검색 문자열을 그룹으로 디코딩합니다.이것은 되돌아오는 같은 형식 http_build_query 을 지원합니다.
$queryString = "dog[name]=John&dog[age]=12&user_ids[0]=1&user_ids[1]=3";
parse_str($queryString, $result);
// $result will be:
// [
//  'dog' => ['name' => 'John', 'age' => 12], 
//  'user_ids' => ['1', '3']
// ];
parse_str목록(즉, 객체가 아닌 배열)의 정수 키를 생략해도 괜찮습니다.
$queryString = "dog[name]=John&dog[age]=12&user_ids[]=1&user_ids[]=3";
parse_str($queryString, $result);
// Same thing! $result will be:
// [
//  'dog' => ['name' => 'John', 'age' => 12], 
//  'user_ids' => ['1', '3']
// ];
아주 간단해요, 그래요?흥분하지 마.

JavaScript
브라우저의 JavaScript는 URLSearchParams 라는 예쁜 API를 제공합니다. Node입니다.js는 querystring 모듈을 제공합니다.인코딩을 시도해 봅시다.
먼저 브라우저에서 다음을 수행합니다.
let params = {
  dog: {
    name: 'John',
    age: 12
  },
  user_ids: [1, 3]
};
let query = new URLSearchParams(params);
decodeURIComponent(query.toString());
// Gives you: "dog=[object+Object]&user_ids=1,3"
"[객체+객체]"?예, URLSearchParams는 값을 기준으로 객체를 지원하지 않습니다.제공된 값을 문자열로 변환합니다.일반 대상의 .toString() 는 '[object]' 를 되돌려줍니다.
또한: 이것은 그룹 파라미터를 처리한 것처럼 보이지만, 없습니다. 그룹 .toString() 은 쉼표로 연결된 값을 되돌려줍니다.이 점을 테스트하기 위해서 query.getAll('user_ids') 호출을 시도하면 두 개의 독립된 항목을 포함하는 문자열 '1, 3' 을 포함하는 그룹을 하나의 항목으로 만들 수 있습니다.
그러나 URLSearchParams는 배열을 지원합니다.하지만 너는 한 번에 하나를 추가해야 한다.이 기능은 다음과 같습니다.
let query = new URLSearchParams();
query.append('user_ids', 1);
query.append('user_ids', 3);
decodeURIComponent(query.toString());
// Gives you: "user_ids=1&user_ids=3"
query.getAll('user_ids');
// Gives you: [1, 3] (an actual array)
난 절대 싫어!😕 어쨌든 우리는 노드로 돌아갑시다.js:
let qs = require('querystring');
let params = {
  dog: {
    name: 'John',
    age: 12
  },
  user_ids: [1, 3]
};
qs.stringify(params);
// Gives you: "dog=&user_ids=1&user_ids=3"
하!보기에 그것은 단지 건너뛰는 것 같다. dog 대상.의사는 다음과 같이 설명했다.

It serializes the following types of values passed in obj: <string> | <number> | <boolean> | <string[]> | <number[]> | <boolean[]>. Any other input values will be coerced to empty strings.


네.나는 [object Object]보다 낫다고 생각한다.¯\_(ツ)_/¯
배열의 경우 querystring URLSearchParams를 따릅니다. 그러나 항목에 별도로 첨부할 필요는 없습니다.
그래, 디코딩 어때?
브라우저:
let query = new URLSearchParams("user_ids=1&user_ids=3");
query.getAll('user_ids');
노드:
qs.parse("dog=&user_ids=1&user_ids=3");
// Gives you: { dog: '', user_ids: [ '1', '3' ] }
매우 비슷한 행위.
PHP 스타일의 쿼리 문자열을 디코딩할 수 있지만 원하는 방식으로 작동하지는 않습니다.모든 열쇠는 원래대로 돌려줄 것이다.
let queryString = "dog[name]=John&dog[age]=12&user_ids[]=1&user_ids[]=3";
let query = new URLSearchParams(queryString);
query.getAll('user_ids'); // Gives you: []
query.get('dog'); // Gives you: null

// *This* is what it parses
query.get('dog[name]'); // Gives you: "John"
query.get('dog[age]'); // Gives you: "12"
query.get('user_ids[]'); // Gives you: ["1", "3"]
qs.parse("dog[name]=John&dog[age]=12&user_ids[]=1&user_ids[]=3");
// Gives you:  {
//   'dog[name]': 'John',
//   'dog[age]': '12',
//   'user_ids[]': [ '1', '3' ]
// }
JS 스타일의 배열 질의 매개변수를 PHP로 구문 분석하려고 해도 실패합니다.너는 마지막 값만 얻었다.
parse_str("user_ids=1&user_ids=3", $result);
// $result is ["user_ids" => "3"]
그러나 전환점이 하나 있다. Node.js also supports URLSearchParams.이것은 노드에서 조회 파라미터를 사용하는 두 가지 다른 방식(미세한 차이가 있다)이다.js!
내가 틀에 특정된다고 했던 거 기억나?노드js는 PHP 스타일의 검색 매개 변수를 지원하지 않지만 Express(Node.js 프레임워크)는 지원합니다!Express는 "dog[name]=John&dog[age]=12&user_ids[]=1&user_ids[]=3"를 하나의 대상과 하나의 그룹으로 정확하게 해석합니다!그래서, 그래, 이건 언어문제만은 아니야.
오, 이것들은 단지 가능한 방법일 뿐이야.JSON이 객체를 인코딩하여 URL에 넣는 등 언급되지 않은 부분도 있습니다.

백엔드를 구축할 때 무엇을 해야 합니까?
우선, 가능한 한 수조나 대상 조회 파라미터를 사용하지 않는 것이 현명할 수 있다.즉, 때로는 당신이 할 수 없을 때가 있다. 이런 상황에서 가장 좋은 선택은 하나의 방안을 선택하고 의사소통을 하며 견지하는 것이다.
하나의 방안을 선택하려면, 실행 위의 간단한 테스트를 통해 어떤 시스템이 당신의 프레임워크나 언어에서 작동하는지 찾아내십시오👆. (만약 당신의 서비스가 이렇게 사용된다면 전단<form>에서 테스트를 하는 것을 잊지 마세요.)
아니면, 너는 자신의 계획을 세울 수 있다.이것은 보통 좋은 생각은 아니지만, 만약 당신의 요구가 간단하다면, 그것은 더욱 좋을 것이다.예를 들어 문자열 목록만 있으면 매개 변수를 쉼표로 구분된 일반 문자열로 지정하고 서버에서 일부러 쉼표로 구분해서 그룹을 만들 수 있다.이렇게 하면 당신은 틀을 걱정할 필요가 없습니다.
그리고 소통해.당신의 소비자들이 당신이 사용하는 격식이 무엇인지 알게 하세요.API를 구성하는 경우 API 문서에 예를 입력합니다.이렇게 하면 그들은 클라이언트가 구축한 어떤 프레임워크에 의존하지 않고 이 프레임워크의 인코딩을 스스로 처리할 수 있다는 것을 알 수 있다.
마지막으로 버텨라.네가 어떤 방안을 선택하든지 간에 전체 백엔드에서 일치해야 한다.

좋은 웹페이지 즐겨찾기