링크가 데이터를 잃는 이유: 매개변수와 프래그먼트 수정하기
URL에서 &와 #을 구분하고 이중 인코딩을 피하세요. WikiURL과 브라우저로 실제 공유할 링크와 검색 결과를 확인합니다.

열리는 페이지가 예상한 데이터를 받는 것은 아니다
커피와 차를 검색하는 링크를 만들었습니다. 페이지는 열리지만 결과가 의도와 맞지 않습니다. 서버나 단축 서비스를 탓하기 전에 공유한 정확한 주소를 살펴보세요. 가상 예시의 q=cafe&te는 일반적인 폼 매개변수 해석에서 하나의 cafe&te 값이 아닙니다. &가 항목을 나누기 때문입니다. 또한 #precios는 프래그먼트를 나타냅니다. 실제 주소를 시험하기 전에 example.invalid를 해당 검색을 지원하는 자신의 페이지로 바꾸세요.
진단을 세 질문으로 나누세요. 어떤 페이지를 열 것인지, 어떤 데이터를 받아야 하는지, 이후 어떤 부분을 보여 줄 것인지입니다. 버튼에 보이는 글자만이 아니라 링크 URL을 복사합니다. 수정하기 전에 기준 버전을 저장하세요. 이 안내서는 구성 요소를 검토한 뒤 WikiURL로 결과를 확인하도록 제안합니다. 모든 사이트가 q를 인식하거나 성공 응답이 올바른 검색 결과를 뜻한다고 약속하지 않습니다.
https://example.invalid/buscar?q=cafe&te#precios앰퍼샌드가 텍스트의 일부라면 구분자로 쓰지 않기
cafe & te를 문자 그대로 검색하려면 &는 q 값에 포함되어야 합니다. URLSearchParams로 매개변수를 만들 때 인코딩하지 않은 텍스트를 전달하세요. 직렬화하면 해당 문자가 %26으로 표현됩니다. MDN은 이 인터페이스가 매개변수를 텍스트로 바꿀 때 폼 인코딩을 적용하고 공백을 +로 표현한다고 설명합니다. URL의 모든 &를 바꾸라는 뜻은 아닙니다. 일부는 의도적으로 매개변수를 나눕니다.
JavaScript 예시는 기본 주소로 URL을 만들고 검색 값을 설정한 다음 프래그먼트를 따로 추가합니다. 로컬 JavaScript 환경에서 실행하면 가상 도메인에 검색을 보내지 않고 결과를 볼 수 있습니다. 프로그래밍하지 않는다면 글자를 수동으로 이어 붙이지 말고 자신의 검색 페이지가 만드는 링크를 사용하세요. 예상 값과 사이트의 결과를 비교합니다. 링크에서 %26이 보인다고 특정 앱의 데이터 해석 방식이 확인되는 것은 아닙니다.
const url = new URL("https://example.invalid/buscar");
url.searchParams.set("q", "cafe & te");
url.hash = "precios";
console.log(url.href);
// https://example.invalid/buscar?q=cafe+%26+te#precios프래그먼트는 서버가 받는 매개변수가 아니다
MDN에 따르면 # 뒤의 프래그먼트는 클라이언트에서 처리되며 리소스를 요청할 때 서버로 전송되지 않습니다. 페이지는 이를 precios 같은 섹션으로 이동하거나 다른 앱 동작에 사용할 수 있습니다. 따라서 q=cafe#te에서 te는 해당 요청에서 서버가 받는 값을 완성하지 않습니다. #이 검색 텍스트의 일부여야 한다면 값 안에서 %23으로 표현합니다. 세 번째 주소가 그 예시입니다.
두 효과를 각각 확인하세요. 검색이 예상 결과를 보여 주는지, 프래그먼트가 원하는 위치에 도달하는지입니다. 섹션이 존재하거나 앱이 프래그먼트를 인식해야 합니다. 서버에서 사이트를 요청하는 확인 도구만으로는 브라우저가 섹션으로 스크롤하는지 알 수 없습니다. 모든 프래그먼트를 지우는 만능 해결책도 피하세요. 받는 사람이 필요로 하던 부분을 없앨 수 있습니다.
https://example.invalid/buscar?q=cafe%23te#precios값은 한 번 인코딩하고 전체 주소는 다시 인코딩하지 않기
RFC 3986은 구성 요소 구분 문자와 데이터를 구분하며 같은 문자열을 반복해서 인코딩하거나 디코딩하는 것에 주의하라고 합니다. 인코딩하지 않은 값을 기대하는 함수에 cafe%26te라는 인코딩된 텍스트를 주면 퍼센트 기호가 %25로 바뀌어 %2526이 나타날 수 있습니다. 한 층을 추가한 것이지 원하는 검색을 자동으로 보존한 것은 아닙니다. 예시의 두 줄로 이 변화를 알아볼 수 있습니다.
수정은 데이터 출처에 달려 있습니다. 사람이 입력한 텍스트라면 매개변수를 구성하는 인터페이스에 인코딩하지 않은 상태로 전달합니다. 이미 유효한 전체 URL이라면 주소를 하나의 값처럼 취급해 전부 다시 인코딩하지 마세요. 각 함수나 폼이 어떤 입력을 받는지 기록합니다. %, &, #을 일괄 치환하는 수정은 피하세요. 올바른 구분자, 필요한 매개변수 또는 바꾸려 하지 않은 경로를 변경할 수 있습니다.
q=cafe%26te
q=cafe%2526te응답은 WikiURL, 콘텐츠는 브라우저로 검토하기
실제 공개 주소가 생기면 WikiURL URL 확인 도구에 붙여 넣으세요. 반환된 HTTP 상태와 최종 목적지를 검토합니다. 구현은 서버에서 요청하고 리디렉션을 따라가므로 예상하지 못한 목적지를 찾는 데 도움이 됩니다. 관리 링크, 비밀번호 또는 비공개 데이터가 들어 있는 주소를 넣지 마세요. 예시의 example.invalid는 가상 목적지이므로 확인하지 않습니다.
실제 버전을 브라우저에서도 열어 검색과 섹션을 확인합니다. 성공 응답이 예상한 필터를 적용하지 않은 페이지를 불러올 수 있습니다. 리디렉션이 있다면 매개변수를 기준 버전과 비교하고 브라우저에서 프래그먼트를 관찰하세요. 확인 도구는 앱 논리를 대신 해석하거나 안전을 인증하지 않으며 계정의 콘텐츠 접근 권한을 증명하지도 않습니다. 응답 증거와 기능 검토를 결합하는 것이 목적입니다.
다른 사람이 받을 복사본을 테스트하기
최종 링크를 공유할 채널에 붙여 넣고 널리 배포하기 전에 그 복사본을 여세요. 문장 끝 마침표가 포함되지 않았는지, 복사 중 일부가 빠지지 않았는지, 보이는 텍스트를 목적지로 착각하지 않았는지 확인합니다. 공개 콘텐츠라면 관리자 세션에 의존하지 않고 테스트하세요. QR로 바꾼다면 원본 파일뿐 아니라 스캔에서 표시되는 주소도 확인합니다.
작은 기록을 남기세요. 원래 주소, 예상 검색 값, 의도한 프래그먼트, 공유 URL과 관찰 결과입니다. 실패하면 해당 구성 요소로 돌아가 수정 후 다시 테스트합니다. 확인한 버전만 게시하세요. 이렇게 매개변수 구성 오류, 목적지를 바꾸는 리디렉션과 브라우저 동작을 구분할 수 있습니다. 열리는 링크를 보내려던 모든 데이터가 유지된다는 보장으로 여기지 않게 됩니다.