HTTPS 페이지에서 HTTP AJAX 작업을 실행할 때 "혼합 콘텐츠 차단됨"


110

crm (ViciDial)에 제출하는 양식이 있습니다 (이 방식으로 필요하므로 GET을 통해). 양식을 성공적으로 제출할 수 있지만 그렇게하면 crm의 처리 파일이 성공 텍스트를 에코하고 그게 다입니다.

이 텍스트 대신 웹 사이트에 감사 페이지를 표시하고 싶기 때문에 AJAX를 사용하여 양식을 제출하고 필요한 페이지로 리디렉션하기로 결정했지만 브라우저에서이 오류가 발생합니다.

혼합 콘텐츠 : ' https://page.com ' 의 페이지가 HTTPS를 통해로드되었지만 안전하지 않은 XMLHttpRequest 엔드 포인트 ' http://XX.XXX.XX.XXX/vicidial/non_agent_api.php?queries=query=data를 요청했습니다. '. 이 요청은 차단되었습니다. 콘텐츠는 HTTPS를 통해 제공되어야합니다.

이것은 내 AJAX 스크립트입니다.

    <script>
    SubmitFormClickToCall = function(){

        jQuery.ajax({
            url: "http://XX.XXX.XX.XX/vicidial/non_agent_api.php",
            data : jQuery("#form-click-to-call").serialize(),
            type : "GET",
            processData: false,
            contentType: false,
            success: function(data){
                window.location.href = "https://www.example.com/thank-you";
            }
        });
    }
    </script>

URL에 https를 설정하는 것만으로는 작동하지 않습니다. GET을 통해 데이터를 제출하고 사용자를 감사 페이지로 리디렉션 할 수있는 방법이 있습니까?

============================

여기서 문제는 혼합 콘텐츠였습니다. 이것은 내가 HTTPS를 통해 페이지를로드하고 HTTP에있는 API를 AJAX를 통해 공격하려한다는 것을 의미합니다. 그러나 브라우저는 우리가 그렇게하는 것을 허용하지 않습니다.

따라서 API를 HTTPS로 설정할 수없는 경우 (제 경우) 다른 방식으로 접근 할 수 있습니다.

주요 문제는 혼합 콘텐츠 문제가 아니라 API에 데이터를 제출하고 사용자를 멋진 감사 페이지로 리디렉션하려는 것이 었습니다. AJAX를 사용하는 대신 데이터를 수신하는 php 파일을 만들어 curl을 사용하여 API로 보내고 (서버 측에서는 혼합 콘텐츠 문제가 없음) 행복한 사용자를 멋진 감사 페이지로 리디렉션합니다.


API의 보안 버전이 있습니까? 보안 사이트를 오리진으로 사용하는 경우 HTTPS를 통해 요청해야합니다.
Cameron Tinker 2015

1
아니요, 그렇게 할 수있는 다른 방법이 있습니까? Ajax없이 제출 양식 만 사용하면 요청이 진행됩니다
StormRage

XX.XXX.XX.XXHTTP 를 통해 프록시하기 위해 Apache에서 HTTPS URL을 만들 수 있습니다 . 그러나 HTTP의 목적이 사용자의 정보를 보호하는 것이라면 서버 간의 경로가 공용 인터넷을 통과하지 않도록주의해야합니다.
halfer

답변:


90

HTTPS를 사용하여 브라우저에 페이지를로드하면 브라우저는 HTTP를 통한 리소스로드를 거부합니다. 시도한대로 HTTP 대신 HTTPS를 사용하도록 API URL을 변경하면 일반적으로이 문제가 해결 됩니다. 그러나 API는 HTTPS 연결을 허용하지 않아야합니다. 따라서 기본 페이지에서 HTTP를 강제 실행하거나 HTTPS 연결을 허용하도록 요청해야합니다.

참고 사항 : AJAX로로드하는 대신 API URL로 이동하면 요청이 계속 작동합니다. 이는 브라우저가 보안 페이지 내에서 리소스를로드하지 않고 대신 안전하지 않은 페이지를로드하고이를 수락하기 때문입니다. 그러나 AJAX를 통해 사용할 수 있으려면 프로토콜이 일치해야합니다.


1
좋아, API가 내 서버에 있습니다. https로 만들 수있는 가이드가 있나요?
StormRage

1
@StormRage 당연히! 어떤 유형의 서버를 실행하고 있습니까? 아파치? 공유 호스팅입니까 아니면 개인 서버입니까?
Mikel Bitson 2015

@StormRage 추가 도움이 필요하면 알려주십시오. 그렇지 않으면 투표는 당신이 여기에서 얻는 공공 지원을 장려 할 것입니다.
Mikel Bitson 2015

1
늦어서 죄송합니다. AJAX를 사용하지 않고 해결했습니다. 솔루션에는 일부 워드 프레스 기능 / php curl이 포함되어 있습니다. 가능한 한 빨리 솔루션을 게시해야합니다. 질문을 편집하고 솔루션을 작성해야합니까? "자신의 질문에 답하십시오"라는 버튼을 사용해야합니까?
StormRage 2015

1
여기에서 답변의 관련 부분을 강조했습니다. 이에 대한 유일한 실질적인 해결책은 HTTPS를 사용하는 것입니다
Liam

131

우리가 제어하지 않는 타사 API를 사용하고 있으므로 HTML 페이지에 다음 코드를 추가하여이 문제를 해결했습니다.

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

이것이 도움이되기를 바랍니다.


8
이렇게 http하면 사용할 모든 요청 이 업그레이드 https되므로 각 호출에 대해 프로토콜을 변경할 필요가 없습니다.
eithed

3
이것은 나를 위해 일하지만, 불행히도 이것은 인터넷 익스플로러에서 작동하지 않습니다 developer.mozilla.org/en-US/docs/Web/HTTP/Headers/...
인 Ciaran 갤러거

2
나는 이것을 시도했지만 지금은 크롬에서 파이어 폭스와 net :: ERR_SSL_PROTOCOL_ERROR에서 CORS 오류가 발생합니다. 내 웹 페이지가 이전에 http 였기 때문에 모든 통화가 작동한다는 것을 알고 있지만 이제는 https로 변경했기 때문에 이러한 통화가 작동하지 않습니다. 기본 html 파일에 추가 할 수있는 다른 항목이 있습니까? @Juanma Menendez 단계를 따르면 모든 통화가 작동하지만 모든 사용자가 이것을 할 것이라고 기대할 수 없기 때문입니다.
Otorrinolaringologista -man

나는 당신의 대답을 찾을 때까지 몇 시간 동안이 문제로 고생했습니다.
Muhab

우리는이 솔루션이 우리의 경우에 효과가 있음을 확인합니다. 앞으로도 도움이 될 것입니다. 우리는 세그먼트 화 된 HTTP 라이브 스트리밍 / 주문형 비디오 기능 (예 : www.example.com/blabla/master.m3u8. 모두 http에서 잘 작동했습니다. 그러나 https로 마이그레이션하면 작동하지 않습니다. 이니셜 master.m3u8https요청 을 수행 할 수 있지만 다음 세그먼트 비디오 청크가 항상 사용 하고 있다는 것을 알았습니다 http(타사 모듈을 사용하고 있기 때문). 우리가 무엇을 조정하더라도 https. 이 정책을 사용하고 즉시 매력처럼 작동했습니다!
rahmatns

34

신뢰할 수있는 웹 페이지를 방문하는 중이고 빠르게 진행하려면 다음을 수행하십시오.

1- 주소 표시 줄의 맨 오른쪽에있는 방패 아이콘을 클릭합니다.

Google 크롬에서 혼합 콘텐츠 허용

2- 팝업 창에서 "그래도로드"또는 "안전하지 않은 스크립트로드"를 클릭합니다 (Chrome 버전에 따라 다름).


Chrome 브라우저를 항상 (모든 웹 페이지에서) 혼합 콘텐츠를 허용하도록 설정하려는 경우 :

1- 열린 Chrome 브라우저에서 키보드의 Ctrl + Shift + Q를 눌러 Chrome을 강제로 닫습니다. 다음 단계를 수행하기 전에 Chrome을 완전히 닫아야합니다.

2- Google Chrome 바탕 화면 아이콘 (또는 시작 메뉴 링크)을 마우스 오른쪽 버튼으로 클릭합니다. 속성을 선택합니다.

3- 대상 필드의 기존 정보 끝에 "--allow-running-insecure-content"를 추가합니다 (첫 번째 대시 앞에 공백이 있습니다.)

4- 확인을 클릭합니다.

5- Chrome을 열고 이전에 차단 된 콘텐츠를 실행 해보십시오. 이제 작동합니다.


4
이것은 OP와 같이 브라우저에서 사이트가 작동하도록 설정을 변경하고 싶지 않은 사용자를 위해 웹 사이트를 디자인하는 사람들에게는 아무 효과가 없습니다.
smallpants

12

이 오류의 원인은 매우 간단합니다. 서버가 HTTPS를 통해 실행되는 동안 AJAX가 HTTP를 통해 호출을 시도하므로 서버가 AJAX 호출을 거부합니다. 기본 HTML 파일의 head 태그 안에 다음 줄을 추가하여이 문제를 해결할 수 있습니다.

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

허용하지만 요청은 https
BG BRUNO

나의 경우에는. 서버 전용 HTTP 요청. 이 <메타>는 작동하지 않습니다. 브라우저는 URL에서 요청 오류라고 말합니다.
iHad 169

1

API 코드가 node.js 서버 에서 실행되는 경우 Apache 또는 NGINX가 아닌 여기에주의를 집중해야합니다. Mikel이 맞습니다. API URL을 HTTPS로 변경하는 것이 정답이지만 API가 node.js 서버를 호출하는 경우 HTTPS를 설정하는 것이 좋습니다! 물론 node.js 서버는 사용되지 않은 포트에있을 수 있으며 포트 443 일 필요는 없습니다.


API는 써드 파티, 그래서 내가 HTTPS로 설정할 수있는 방법이 없었다, 당신은 내가 맞추려고 된 URL에서 볼 수 있듯이, API는 PHP로 코딩 된
스톰레이지

@StormRage 귀하의 질문과 Mikel의 답변은 내 문제에 대한 해결책으로 이어 졌으므로 내 답변이 귀하의 상황에 실제로 적용되지는 않지만 여기에 메모 할 것이라고 생각했습니다.
mcmacerson

글쎄요, 당신과 Mikel이 옳습니다. 가장 합리적인 해결책은 API에서 ssl을 사용하는 것입니다.하지만이 맥락에서 저는 타사 API이기 때문에 그렇게 할 수 없었지만 wordpress 또는 레거시 사이트는 데이터를 백엔드로 보내고 서버 내의 API로 요청을 보낼 수 있습니다.
스톰레이지

동일한 호스트에서 서버 측으로 laravel에 의해 api를 PWA로 PWA로 구현 했으므로이 기사에서 언급 한 동일한 오류가 있습니다. stackoverflow.com/q/56157129/308578
saber tabatabaee yazdi

1

Ajax Post 메소드를 사용하는 대신 요소와 함께 동적 양식을 사용할 수 있습니다. 페이지가 SSL에로드되고 제출 된 소스가 SSL이 아닌 경우에도 작동합니다.

양식 요소의 값 값을 설정해야합니다.

실제로 새로운 동적 양식은 대상 속성이 '_blank'로 설정된 경우 브라우저의 별도 탭에서 SSL이 아닌 모드로 열립니다.

var f = document.createElement('form');
f.action='http://XX.XXX.XX.XX/vicidial/non_agent_api.php';
f.method='POST';
//f.target='_blank';
//f.enctype="multipart/form-data"

var k=document.createElement('input');
k.type='hidden';k.name='CustomerID';
k.value='7299';
f.appendChild(k);



//var z=document.getElementById("FileNameId")
//z.setAttribute("name", "IDProof");
//z.setAttribute("id", "IDProof");
//f.appendChild(z);

document.body.appendChild(f);
f.submit()

나는 실제로 API를 치고 싶지만 get 요청을 통해 귀하의 방법으로 수행하면 실제로 양식을 제출하지만 이제는 API에서 응답을 읽는 데 어려움을 겪습니다. 그 AJAX에 대한 추측하거나 XMLHttpRequest의 유일한 옵션입니다 원인
싯다 르트 나라 얀 Choudhary

intereting 솔루션 :-)
BG BRUNO

간단하고 화려한
Harkal

0

나는 같은 문제 였지만 나에게 문제는 ng 빌드 명령이었습니다. 나는 "ng build --prod"를하고 있었는데 "ng build --prod --base-href / applicationname /"로 수정했습니다. 그리고 이것은 내 문제를 해결했습니다.


0

제 경우에는 localhost가 http이고 배포 된 버전은 https이므로이 스크립트를 사용하여 https에 대해서만 http-equiv 메타 태그를 추가했습니다.

if (window.location.protocol.indexOf('https') == 0){
  var el = document.createElement('meta')
  el.setAttribute('http-equiv', 'Content-Security-Policy')
  el.setAttribute('content', 'upgrade-insecure-requests')
  document.head.append(el)
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.