글

URLSearchParams append·set: UTM을 더할 때 같은 키가 겹치는 이유

이미지
URLSearchParams.append()는 같은 키가 있어도 새 값 쌍을 추가합니다. set()은 해당 키의 값을 지정하면서 같은 키의 다른 값은 지웁니다. UTM을 붙인 주소에서 같은 이름이 두 번 보인다면 두 메서드의 역할부터 확인하세요. 목차 1. append는 새 쌍을 덧붙입니다 2. set은 같은 키의 값을 하나로 정합니다 3. 바꾼 주소와 원본을 따로 비교합니다 1. append는 새 쌍을 덧붙입니다 링크 목록에서 반복 키를 발견했다고 곧바로 오류라고 지우지는 마세요. 검색 필터처럼 여러 값을 의도한 주소도 있을 수 있습니다. 먼저 이 주소에서 키 하나가 한 값만 가져야 하는지, 여러 선택을 표현하는지 구분하는 편이 좋습니다. 아래는 외부로 요청하지 않는 문자열 예시입니다. 실제 서비스나 추적 링크에 접속해서 결과를 얻었다는 뜻은 아닙니다. const p = new URLSearchParams('tag=book&tag=life'); p.append('tag', 'travel'); console.log(p.toString()); // tag=book&tag=life&tag=travel 2. set은 같은 키의 값을 하나로 정합니다 원본 조작 결과 tag=book&tag=life append('tag','travel') tag가 세 번 tag=book&tag=life set('tag','travel') tag=travel 키가 없는 상태 set('tag','travel') 새 tag 쌍 생성 기존 UTM을 새로운 값 하나로 교체하려는 목적과, 검색 필터를 하나 더 넣으려는 목적은 다릅니다. 메서드 이름을 외우기 전에 결과 주소에서 몇 개의 같은 키가 남아야 하는지를 먼저 적어보세요. MDN append의 같은 키 추가 예시 보기 MDN set의 값 교체·다른 값 제거 설명 보기 3. 바꾼...

URLSearchParams.sort()로 쿼리 정렬: 같은 키의 값 순서는 바뀌지 않습니다

이미지
URLSearchParams.sort() 는 쿼리의 키를 기준으로 현재 객체를 정렬합니다. 같은 키가 여러 번 나오면 그 값들의 상대적인 순서는 유지하며, 정렬된 문자열을 반환하지는 않습니다. 추출한 링크 목록을 비교하려고 정렬할 때는 ‘키 정렬’과 ‘값 정렬’, ‘중복 제거’를 같은 작업으로 생각하지 마세요. 원본과 작업용 객체를 구분하면 무엇이 바뀌었는지 설명하기 쉽습니다. 목차 1. 키 정렬과 안정 정렬의 의미 2. 원문을 보존하는 짧은 예제 3. 반환값과 결과를 나눠 기록 4. 자주 묻는 질문 1. 키 정렬과 안정 정렬의 의미 MDN은 sort()가 객체를 제자리에서 변경하며 키의 UTF-16 코드 단위 값을 기준으로 정렬한다고 설명합니다. 같은 키끼리는 기존 상대 순서를 보존하는 안정 정렬입니다. 따라서 이름이 같은 키의 값을 작은 숫자부터 다시 배열하는 기능으로 읽으면 안 됩니다. 아래 자체 예제에서는 a 값 2와 5가 그 순서대로 남습니다. 반복된 키가 하나로 합쳐지는 작업도 아닙니다. 2. 원문을 보존하는 짧은 예제 const original = "b=7&a=2&a=5"; const working = new URLSearchParams(original); const returned = working.sort(); console.log(original); // b=7&a=2&a=5 console.log(working.toString()); // a=2&a=5&b=7 console.log(returned); // undefined 원문 문자열은 별도의 변수에 남겨두고 작업용 객체를 정렬하는 예시입니다. 실제 주소를 수집했다면 원래 주소를 보관하는 열과 정렬 결과를 보는 열을 나눠두세요. 정렬한 결과를 원본 자료인 것처럼 덮어 적지 않는 방식입니다. 실제 업무에 적용하기 전에는 공개해도 되는 연습용 쿼리로 동작을 확인하세요. 고객정보나 인증 토큰이 들어 있는 실제 링크를 공유 예제로 옮길 ...

블로그 링크의 sponsored·ugc: 주소와 링크 관계를 다른 열에 기록하세요

이미지
블로그 링크를 정리할 때 href는 목적지 주소, rel은 링크와 맺는 관계를 읽는 항목입니다. sponsored나 ugc가 붙었다고 주소가 달라지거나 클릭할 수 없게 되는 것은 아니므로 목록에서도 두 값을 다른 열에 보관하세요. 목차 1. 관계 표시는 링크를 막는 버튼이 아닙니다 2. rel 값은 하나만 있을 수도, 여러 개일 수도 있습니다 3. nofollow와 색인 차단을 같은 칸에 쓰지 마세요 4. 자주 묻는 질문 1. 관계 표시는 링크를 막는 버튼이 아닙니다 Google 검색 문서는 광고·유료 배치 링크에 sponsored, 댓글과 포럼 등 사용자 작성 콘텐츠의 링크에 ugc를 사용하는 방식을 설명합니다. 일반 링크에는 이런 관계를 표시하는 rel이 반드시 필요한 것은 아니며, 다른 값이 맞지 않는 경우의 nofollow도 구분합니다. 따라서 링크 목록에서 주소가 같다고 모든 링크를 한 줄로 합치면 서로 다른 관계 정보를 잃을 수 있습니다. 같은 목적지라도 본문에서 직접 작성한 안내, 댓글의 링크, 유료 배치가 각각 있는지 원래 위치를 함께 남겨두세요. 2. rel 값은 하나만 있을 수도, 여러 개일 수도 있습니다 공식 문서는 여러 rel 값을 공백 또는 쉼표로 나눠 쓸 수 있다고 안내합니다. 예를 들어 사용자 작성 콘텐츠이면서 유료 관계가 있다면 두 관계가 함께 표시될 수 있습니다. 추출 도구에서 rel 문자열을 한 개의 값으로만 가정하지 않는 이유입니다. 목록의 열 보관할 정보 문구 독자에게 보이는 링크 설명 href 쿼리와 앵커를 포함한 목적지 rel 현재 저장된 관계 값 전체 위치·맥락 본문·댓글·유료 배치 등 확인한 사실 값이 없다고 곧바로 잘못된 링크로 분류하지 말고 맥락을 보세요. 반대로 sponsored가 보이지 않는다고 실제 유료 관계가 없다고 확정할 수도 없습니다. 원고의 운영 사실과 공개된 링크 속성을 대조하는 작업이 필요합니다. Google 링크 관계 속성 공식 안내 보기 3. nofollow와 색인 차단을 같은 칸에 쓰지 마세요...

블로그 링크의 noreferrer: 목적지 URL과 Referer 정보는 서로 다릅니다

이미지
noreferrer는 링크의 목적지 주소를 지우는 속성이 아닙니다. MDN은 이 키워드가 이동할 때 Referer 헤더와 참조 정보를 생략하도록 지시한다고 설명합니다. href에 적힌 쿼리와 출처 헤더를 같은 것으로 취급하지 마세요. 목차 1. 링크 코드의 두 부분부터 나누기 2. URL과 Referer 비교 3. 공개 글에서 남길 점검 메모 4. 새 탭 동작과도 따로 보기 5. 자주 묻는 질문 1. 링크 코드의 두 부분부터 나누기 <a href="https://example.com/guide?utm_source=sample" target="_blank" rel="noreferrer">안내 읽기</a> 위 코드는 설명용 예제이며 실제 배포 주소가 아닙니다. href에는 목적지가, rel에는 링크 관계를 나타내는 키워드가 적혀 있습니다. noreferrer를 넣는 동작 자체가 href의 utm_source 값을 삭제하는 것은 아닙니다. 공개 글을 검수할 때는 편집기에서 적은 주소와 최종 도착 주소를 먼저 대조하세요. 다른 링크 처리나 서버의 이동 규칙이 있으면 결과는 달라질 수 있으므로, 원래 코드만으로 최종 주소까지 확인했다고 기록하지 않습니다. 2. URL과 Referer 비교 항목 무엇을 확인하나요 같게 보지 않을 것 href의 쿼리 링크 주소에 직접 붙인 값 브라우저가 보내는 출처 헤더 Referer 정보 어디에서 이동했는지 전달되는 요청 정보 목적지 주소 그 자체 noreferrer 참조 정보 생략 지시 URL의 모든 추적 값 제거 분석 도구 집계 해당 도구의 실제 수집·분류 결과 링크 클릭 또는 주소 확인만으로 집계 완료 단정 MDN은 noreferrer가 noopener도 지정된 것처럼 동작한다고 설명합니다. 하지만 이 설명을 모든 익명성이나 모든 추적 차단의 보장으로 확대하지 않습니다. 무엇이 주소이고 무엇이 별도 요청 정보인지 구분하는 것이 먼저입니다. 3. 공개 글...

Python3.12 urlsplit 앞 공백이 사라질 때: 원본 문자열과 분해 결과를 따로 보관

이미지
Python3.12의 urlsplit 결과는 원본 문자열을 한 글자도 바꾸지 않고 보관하는 사본이 아닙니다. 공식 문서는 앞쪽 C0 제어 문자·공백을 제거하고, 줄바꿈·캐리지리턴·탭은 URL의 어느 위치에서든 제거한다고 설명합니다. 링크 수집 검수에서는 원본과 분해 결과를 다른 칸에 남겨야 합니다. 목차 1. 원본과 geturl 결과를 같은 값으로 덮어쓰지 않기 2. 눈에 보이는 문자열만 복사하면 놓칠 수 있습니다 3. 링크 목록에 변화 이유를 남기기 4. 자주 묻는 질문 1. 원본과 geturl 결과를 같은 값으로 덮어쓰지 않기 공식 문서는 앞쪽 제어 문자·공백 제거를3.12 변경으로, ASCII 줄바꿈·탭 제거를3.10 변경으로 구분합니다. 지금 사용하는 버전의 동작을 확인하고, 화면에 보이지 않는 문자가 있었는지 원본 표현을 함께 살펴보세요. urlsplit은 URL의 안전성·유효성을 전부 검증하는 함수도 아닙니다. from urllib.parse import urlsplit raw = ' https://example.com/a\nb' parts = urlsplit(raw) print(repr(raw)) print(parts.geturl()) # 재조합 결과: https://example.com/ab 실행 환경 Python3.12에서 확인한 독립 예시입니다. example.com은 예시용 주소이며 이 코드는 네트워크 요청을 보내지 않습니다. Python3.12 공식 urlsplit 변경 사항 확인 2. 눈에 보이는 문자열만 복사하면 놓칠 수 있습니다 보관할 값 용도 구분할 것 원본 raw 실제 받은 문자열 보존 분해한 결과로 덮어쓰지 않기 repr(raw) 줄바꿈·탭 등 관찰 보기용 표현과 원래 문자열 parts.geturl() 분해 결과에서 재조합한 URL 원본과 완전 동일하다는 추정 검수 메모에 repr 문자열을 남기는 것은 보기 위한 방법입니다. repr 결과를 그대로 새 링크 주소로 붙여 넣는 작업과는 다릅니다. 주소를 실제로 사...

Python 3.12 unquote 뒤 �가 보일 때: replace·strict와 원본 바이트 비교

이미지
Python 3.12의 unquote는 기본적으로 UTF-8을 사용하고, 잘못된 바이트열을 만났을 때 errors="replace"로 대체 문자를 넣습니다. 보기 좋은 한글로 바꾸려다가 �가 생겼다면, 변환 결과로 원본 주소를 덮어쓰지 않는 것이 먼저입니다. 목차 1. 짧은 입력으로 차이를 확인하기 2. 문자열 대체와 원본 바이트는 다른 결과입니다 3. 링크 목록에는 원본·표시·검토를 나누세요 4. 자주 묻는 질문 1. 짧은 입력으로 차이를 확인하기 네트워크 요청 없이 아래 문자열만으로 비교할 수 있습니다. %FF는 이 연습에서 의도적으로 넣은 UTF-8 오류 입력입니다. 실제 공개 글이나 고객 주소를 예제로 복사할 필요는 없습니다. from urllib.parse import unquote, unquote_to_bytes raw = "%FF" print(repr(unquote(raw))) # '�' print(unquote_to_bytes(raw)) # b'\xff' try: unquote(raw, errors="strict") except UnicodeDecodeError: print("review needed") Python 3.12 unquote 오류 처리 원문 보기 2. 문자열 대체와 원본 바이트는 다른 결과입니다 방법 예제의 결과 목록에 남길 점 unquote(raw) 대체 문자 �가 포함된 문자열 오류가 없었다고 판단하지 않기 errors="strict" UnicodeDecodeError 발생 별도 검토 대상으로 남기기 unquote_to_bytes(raw) 바이트 b'\xff' 어떤 문자 인코딩인지 아직 결정하지 않음 공식 문서는 unquote_to_bytes가 %xx를 바이트로 되돌리는 기능이라고 설명합니다. 바이트를 얻었다고 원래 작성자가 의도한 글자를 복원한 것은 아닙니다. 원문이 어떤 인코딩...

Python 3.12 urlparse의 allow_fragments=False: #뒤를 지우는 옵션이 아닙니다

이미지
urlparse에서 allow_fragments=False를 지정한다고 #뒤가 삭제되지는 않습니다. fragment로 인식하지 않은 내용은 경로·매개변수·쿼리의 일부로 남을 수 있습니다. 빈 fragment 칸만 보고 원문에도 #가 없었다고 판단하지 마세요. 목차 1. False는 삭제가 아니라 인식 방식입니다 2. 같은 주소를 두 옵션으로 비교하세요 3. 링크 목록에는 옵션도 남기세요 4. 자주 묻는 질문 1. False는 삭제가 아니라 인식 방식입니다 Python3.12 공식 문서는 allow_fragments가 거짓이면 fragment 식별자를 인식하지 않고 경로·매개변수·쿼리의 일부로 분해하며, 반환된 fragment는 빈 문자열이 된다고 설명합니다. “별도 칸으로 나누지 않는다”와 “문자열에서 제거한다”는 서로 다른 처리입니다. Python allow_fragments 인수의 공식 정의 보기 2. 같은 주소를 두 옵션으로 비교하세요 from urllib.parse import urlparse raw = "https://example.org/read?topic=camp#fees" for allow in (True, False): parts = urlparse(raw, allow_fragments=allow) print(allow, repr(parts.query), repr(parts.fragment)) # True 'topic=camp' 'fees' # False 'topic=camp#fees' '' 입력·옵션 query fragment 또는path ?topic=camp#fees / True topic=camp fragment = fees ?topic=camp#fees / False topic=camp#fees fragment = 빈 문자열 /read#fees / False 빈 문자열 path = /read#fees 예시는 실제 사이트...