在HTTPS页面中运行HTTP AJAX操作时,“混合内容被阻止”


108

我有一个要提交给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提交数据并将用户重定向到我的thankyou页面?

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

这里的问题是内容混合,这意味着我通过HTTPS加载了一个页面,并试图通过AJAX命中HTTP中的API。但是浏览器不允许我们这样做。

因此,如果您不能将API设置为HTTPS(这是我的情况),我们仍然可以采用其他方法来处理。

主要问题不是混合内容问题,而是我想将数据提交到API并将用户重定向到精美的感谢页面。我没有使用AJAX,而是制作了一个php文件,该文件接收接收到的数据,使用curl将其发送到API(因为这是在服务器端完成的,没有混合的内容问题),并将我满意的用户重定向到了精美的感谢页面。


您是否有API的安全版本?如果您使用安全站点作为源,则需要通过HTTPS请求。
卡梅隆·廷克

1
不,我没有,还有其他方法可以做到吗?我的意思是,如果仅使用不使用Ajax提交的表单,请求就会通过
StormRage 2015年

您可以在Apache中创建HTTPS URL,以XX.XXX.XX.XX通过HTTP 代理。但是,如果HTTP的目的是保护用户信息,则需要注意服务器之间的路由不会经过公共Internet。
2015年

Answers:


89

如果使用HTTPS在浏览器中加载页面,则浏览器将拒绝通过HTTP加载任何资源。正如您尝试过的那样,将API URL更改为使用HTTPS而不是HTTP通常可以解决此问题。但是,您的API必须不允许HTTPS连接。因此,您必须在主页上强制使用HTTP或请求它们允许HTTPS连接。

请注意以下事项:如果您转到API URL,而不是尝试使用AJAX加载请求,则该请求仍然有效。这是因为浏览器未从安全页面内加载资源,而是正在加载不安全页面并接受该页面。为了使它可以通过AJAX使用,协议应该匹配。


1
好的,API在我的服务器中,我可以按照任何指南将其设为https吗?
StormRage

1
@StormRage绝对!您正在运行哪种类型的服务器?阿帕奇?是共享主机还是专用服务器?
Mikel Bitson,2015年

@StormRage如果您需要任何进一步的帮助,请告诉我。否则,投票将激励您获得SO方面的公共帮助。
Mikel Bitson

1
抱歉,我迟到了,我没有使用AJAX就能解决它,我的解决方案包括一些wordpress函数/ php curl,请尽快解决我的问题,我应该编辑我的问题并在其中写我的解决方案,还是我应该使用显示“回答您自己的问题”的按钮吗?
StormRage

1
在此处重点说明答案的相关部分。唯一可行的解​​决方案是使用HTTPS
Liam

129

我通过在HTML页面中添加以下代码来解决此问题,因为我们使用的是不受我们控制的第三方API。

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

希望这会有所帮助,并且也有记录。


8
这会升级所有http要使用的请求https,因此您无需为每个呼叫更改协议。
eithed

3
:这为我工作,但不幸的是,这并不与Internet Explorer工作developer.mozilla.org/en-US/docs/Web/HTTP/Headers/...
夏兰·加拉格尔

2
我已经尝试过了,但是现在我在Firefox和Net :: ERR_SSL_PROTOCOL_ERROR上遇到了CORS错误。我知道所有通话均有效,因为我的网页之前是http,但是现在我更改为https,因此这些通话不起作用。还有什么我可以添加到我的主要html文件吗?因为如果我遵循@Juanma Menendez的步骤,所有呼叫都可以工作,但我不能指望每个用户都可以这样做。
Otorrinolaringologista -man19年

数小时来,我一直在努力解决这个问题,直到找到答案为止,非常感谢!
Muhab

我们确认该解决方案适用于我们的情况,也许将来也会对您有所帮助:我们尝试建立分段的HTTP实时流/视频点播功能,例如www.example.com/blabla/master.m3u8。在http上一切都很好。但是,当我们将其迁移到https时,它将无法正常工作。我们发现,最初的master.m3u8请求者可以执行https请求,但是以下分段的视频块始终在使用http(因为我们使用的是第三方模块)。不管我们进行什么调整,它都不会使用https。使用此政策并立即发挥作用!
rahmatns

34

如果您只是访问您信任的网页并且想要快速前进,则:

1-单击地址栏最右侧的屏蔽图标。

允许Google Chrome浏览器中的混合内容

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

此错误的原因非常简单。您的AJAX尝试通过HTTP调用,而服务器通过HTTPS运行,因此您的服务器拒绝调用AJAX。可以通过在主HTML文件的head标记内添加以下行来解决此问题:

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

它允许它,但是请求是https
BG BRUNO

就我而言。服务器唯一的HTTP请求。我尝试此<meta>无法工作。浏览器在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。
StormRage

我通过laravel在同一主机上将api作为服务器端实现了离子,并将离子应用程序作为PWA实现了,因此我在本文中提到了相同的错误stackoverflow.com/q/56157129/308578
saber tabatabaee yazdi

1

除了使用Ajax Post方法之外,还可以将动态表单与element一起使用。即使页面加载了SSL并且提交的源不是SSL,它也将起作用。

您需要设置表单元素的值value。

当目标属性设置为“ _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是唯一的选择
Siddharth Choudhary

有趣的解决方案:-)
BG BRUNO

简单而辉煌
Harkal

0

我是同样的问题,但对我来说,问题是ng build命令。我正在执行“ ng build --prod”,我已将其更正为“ ng build --prod --base-href / applicationname /”。这解决了我的问题。


0

在我的情况下,我的本地主机为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)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.