[character-encoding] “콘텐츠 유형 : application / json; charset = utf-8”은 정말로 의미 하는가?

REST 서비스에 JSON 본문으로 POST 요청을 할 때 Content-type: application/json; charset=utf-8메시지 헤더에 포함시킵니다. 이 헤더가 없으면 서비스에서 오류가 발생합니다. 부분 Content-type: application/json없이도 성공적으로 사용할 수 있습니다 ;charset=utf-8.

정확히 무엇을 charset=utf-8합니까? 문자 인코딩을 지정하지만 서비스가 없으면 제대로 작동합니다. 이 인코딩은 메시지 본문에있을 수있는 문자를 제한합니까?



답변

헤더는 컨텐츠가 인코딩 된 내용을 나타냅니다. 컨텐츠 자체에서 컨텐츠의 유형을 추론 할 수있는 것은 아닙니다. 즉, 컨텐츠를보고 그와 관련된 내용을 반드시 알 필요는 없습니다. 그것이 HTTP 헤더의 목적이며 수신자에게 (어쩌면) 다루고있는 컨텐츠의 종류를 알려줍니다.

Content-type: application/json; charset=utf-8UTF-8 문자 인코딩으로 인코딩 된 컨텐츠를 JSON 형식으로 지정합니다. JSON의 기본 (전용?) 인코딩은 UTF-8이므로 인코딩 지정은 JSON에 대해 약간 중복됩니다. 따라서이 경우 수신 서버는 JSON을 다루고 있으며 인코딩이 기본적으로 UTF-8이라고 가정하므로 헤더와 함께 또는 헤더없이 작동하는 것으로 알고 있습니다.

이 인코딩은 메시지 본문에있을 수있는 문자를 제한합니까?

아니요. 헤더와 본문에 원하는 것을 보낼 수 있습니다. 그러나 둘이 일치하지 않으면 잘못된 결과가 나타날 수 있습니다. 헤더에 내용이 UTF-8로 인코딩되어 있지만 실제로 Latin1로 인코딩 된 내용을 보내도록 지정하면 수신자는 가비지 데이터를 생성하여 Latin1로 인코딩 된 데이터를 UTF-8로 해석하려고 시도 할 수 있습니다. 물론 Latin1로 인코딩 된 데이터를 전송하도록 지정하고 실제로 그렇게하고 있다면 Latin1로 인코딩 할 수있는 256 자로 제한됩니다.


답변

@deceze의 주장을 입증하기 위해 기본 JSON 인코딩은 UTF-8입니다 …

에서 IETF RFC4627 :

JSON 텍스트는 유니 코드로 인코딩해야합니다. 기본 인코딩은 UTF-8입니다.

JSON 텍스트의 처음 두 문자는 항상 ASCII 문자 [RFC0020]이므로 옥텟 스트림이 UTF-8, UTF-16 (BE 또는 LE) 또는 UTF-32 (BE 또는 LE)인지 확인할 수 있습니다. 처음 네 옥텟의 널 패턴을 살펴봄으로써

      00 00 00 xx  UTF-32BE
      00 xx 00 xx  UTF-16BE
      xx 00 00 00  UTF-32LE
      xx 00 xx 00  UTF-16LE
      xx xx xx xx  UTF-8

답변

참고 IETF RFC4627가 로 대체되었습니다 IETF RFC7158 . [8.1] 섹션에서 @Drew가 인용 한 텍스트를 다음과 같이 철회합니다.

Implementations MUST NOT add a byte order mark to the beginning of a JSON text.

답변

@deceze에 동의하지만 질문의 “서비스에서 오류가 발생했습니다” 부분 을 개발하고 싶습니다 .

http 415 로 이러한 종류의 오류가 발생합니다.

HTTP 415 지원되지 않는 미디어 유형 오류

HTTP 415 지원되지 않는 매체 유형 클라이언트 오류 응답 코드는 페이로드 형식이 지원되지 않는 형식이므로 서버가 요청 승인을 거부 함을 나타냅니다.

형식 문제는 요청에 표시된 Content-Type 또는 Content-Encoding 또는 데이터를 직접 검사 한 결과 일 수 있습니다.

즉, https://stackoverflow.com/a/22643964/914284 와 같은 예입니다.

  • 올바른 컨텐츠 유형을 설정해야하며 컨텐츠 유형 추가 : application / json 및 Accept : application / json과 같이 올바른 컨텐츠 유형을 승인해야합니다. 그렇지 않으면 기본값을 가정합니다

답변

다트 http의 구현은 “charset = utf-8″덕분에 바이트를 처리하므로 응답에서 바이트를 읽을 때 “latin-1″폴백 문자 세트를 피하기 위해 여러 구현이 지원합니다. 필자의 경우 응답 본문 문자열의 형식이 완전히 손실되므로 utf8로 수동으로 인코딩하는 바이트를 수행하거나 서버의 API 응답에 해당 헤더 “inner”매개 변수를 추가해야합니다.


답변

HttpClient를 사용하고 content-type이있는 응답 헤더를 가져 오는 중 application/jsonHttpClient가 기본적으로 ISO-8859-1 이므로 유니 코드를 사용하는 외국어 또는 기호와 같은 문자를 잃어 버렸습니다 . 따라서 가능한 문제를 피하기 위해 @WesternGun에서 언급 한대로 명시 적으로 명시하십시오.

서버로 인해 요청 된 헤더 문자 세트 ( method.setRequestHeader("accept-charset", "UTF-8");)를 처리하지 않으므로 응답 데이터를 그리기 바이트로 검색하고 UTF-8을 사용하여 문자열로 변환해야했습니다. 따라서 명시 적이며 기본값을 가정하지 않는 것이 좋습니다.


답변