Python의 requests를 사용하여 multipart/form-data 형식의 데이터를 보낼 때 Content-Ope를 "multipart/form-data"로 설정한 헤더를 전달할 수 없습니다

6480 단어 RequestsHTTPPython
소박한 곳이라 필기를 했습니다.

거치다


외부 API는 Authorization 헤더를 사용해야 하기 때문에 헤더 취득 함수의 공통 함수를 만들고 사용합니다.
API의 내용 유형은 기본적으로'application/json'이 필요합니다. 일부'application/x-www-form-urlencoded'와'multipart/form-data'가 필요하기 때문에 제목 획득용 함수는 매개 변수로 내용 유형을 덮어쓸 수 있습니다.
다음은 실제 설치된 분위기 코드가 아닙니까?
example.py
import requests

...

def get_headers(content_type='application/json'):
  return {
    'Authorization': f'Bearer {fetch_bearer()}',
    'Content-Type': content_type,
    'SecretKey': fetch_secret_key(),
  }

...


url = 'https://httpbin.org/post'
files = {'file': open('image.png', 'rb')}
r = requests.post(
  url,
  files=files,
  headers=get_headers(content_type='multipart/form-data')
)
print(r.text)
헤더를 추가한 것 외에 requests 공식 예시 코드 와 같은 글쓰기를 해야 하지만 오류가 발생했다는 응답을 받았습니다.
API에서도 인증 오류가 발생했습니다. 제목을 생성하는 Authorization 및 SecretKey 함수에 문제가 있습니까?그러나 Postman이나curl에서 같은 함수로 생성된 영패에 제목을 삽입하고 멀티플랫폼/form-data 형식으로 API에서 전원을 켜서 자체 검사하면 특별한 오류가 발생하지 않습니다.

원인


Authorization 및 SecretKey 가 아니라 컨텐츠 유형이기 때문입니다.
위 get_headers는 다음 제목의 사전을 생성합니다.
{
  'Authorization': 'Bearer xxxxx',
  'Content-Type': 'multipart/form-data',
  'SecretKey': 'xxxxx',
}
이 머리글을 사용하면 내용 형식에 boundary를 추가하지 않습니다.
boundary는 메시지를 둘러싼 여러 부분의 경계에 사용되며,multipart/form-data 데이터를 보낼 때 필요한입니다.
예를 들어 Postman에서 multipart/form-data 데이터를 보낼 때의 제목은 이렇게 마음대로 계산하여 보낼 때 주는 것이다.

requests의 경우도 마찬가지다.boundary의 설정은 우리가 일일이 계산하고 설정할 필요가 없고 마음대로 부여할 수 있다.
하지만 이번에는 내용 유형이'multipart/form-data'로 설정된 것이기 때문에
requests가 부여한 기본 내용 형식이 덮어쓰여boundary가 없는 상태가 되었습니다.
이 문제를 해결하는 방법은 간단합니다. 헤더에서 내용 형식을 간단하게 삭제하기만 하면 됩니다.
(get_headers를 개작하는 방법도 있지만 multipart/form-data의 API가 필요한 것은 코드에 있는 한 곳뿐이기 때문에 간단한 방법을 사용합니다)
example.py
url = 'https://httpbin.org/post'
files = {'file': open('image.png', 'rb')}

# headerの辞書からContent-Type削除する
headers = get_headers()
headers.pop("Content-Type")

r = requests.post(url, files=files, headers=headers)
print(r.text)
이렇게 하면 오류가 발생하지 않고 데이터를 정상적으로 발송할 수 있다.
아는 사람에게는 당연하지만 평소에 폼과 편리한 클라이언트 도구를 통해 데이터를 보내면boundary는 아무렇게나 부여되어 의식할 수 있는 기회가 없어 빠져든다...

참고 자료


  • Quickstart — Requests 2.25.1 documentation
  • [HTTP] multipart/form-data의 boundary는 무엇입니까? -Qiita
  • Content-Type - HTTP | MDN  

    좋은 웹페이지 즐겨찾기