본문 바로가기

Flutter

[Flutter] 웹 Mixed Content 에러 쉽고 간단하게 해결하는 방법

플러터 웹 배포 후 공공데이터 API를 호출하는데 데이터가 들어오지 않아서 크롬 개발자 도구를 통해 확인해보니 다음과 같은 에러가 발생했습니다

Mixed Content: The page at '웹앱 URL 주소' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '공공데이터 api 요청 주소'. This request has been blocked; the content must be served over HTTPS.

플러터 웹은 HTTPS 프로토콜로 빌드되는데, 부분적으로 HTTP 프로토콜로 데이터가 들어올 경우 안전하지 않은 요청이라고 판단하여 브라우저에서 차단하게 됩니다. 크롬을 포함한 대부분 브라우저에서 차단하는 것 같습니다. 해당 이슈는 로컬에서는 발생하지 않고 배포 시 발생하기 때문에 테스트 환경에서는 인지하기 어렵습니다.

 

문제를 해결하기 위해 먼저 다음과 같은 방법을 시도해볼 수 있습니다

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

이 코드를 index.html 파일의 헤더에 넣어주면 됩니다. 이렇게 하고 다시 배포해보면 작동은 되지만 사용자가 브라우저에서 http 통신을 허용하는 설정을 해줘야하기 때문에 일반적으로 사용하기는 어렵습니다.

 

또 다른 방법으로는 api 요청 주소를 http를 https로 바꿔주는 것입니다. 다만 이 방법은 api 서버에서 https프로토콜을 지원해야 하지만, 제가 사용하는 공공데이터는 https를 지원하지 않았습니다.

 

이 문제를 근본적으로 해결하기 위해서는 직접 백엔드 서버를 구축해야 하는데 초보자가 하기에는 어려운 방법이므로, 쉽고 간단하게 해결할 수 있는 방법으로 프록시 서버 사용을 추천드립니다. 프록시 서버는 클라이언트와 서버 사이에서 데이터를 중계하는 역할을 하는 서버입니다. 프록시 서버를 사용하면, 우리가 배포한 웹과 프록시 서버는 https로 통신을 하고, 프록시 서버와 공공데이터 api 서버는 http로 통신을 함으로써 문제없이 데이터를 주고받을 수 있게 됩니다.

 

저는 https://cors.sh/ 서비스를 사용했습니다

사용방법이 굉장히 간단합니다. get 또는 post 요청 url 주소 앞에 https://proxy.cors.sh/를 붙여주고 헤더에 서비스 키를 붙여주면 됩니다. 플러터 코드를 예시로 보여드리겠습니다

http.get(
  Uri.parse(
      'https://proxy.cors.sh/http://openapi....'),
  headers: {'x-cors-api-key': '서비스 키'}
  ),
);

서비스 키는 메일주소를 입력하면 메일로 임시 키가 발급됩니다. 임시 키는 3일 동안 사용 가능하고 회원가입 후 결제를 하면 정식 키를 발급받으실 수 있습니다. 이용료는 한달에 4$입니다.

이렇게 하면 https 웹에서도 http 요청이 정상적으로 이루어지는 것을 확인할 수 있습니다.