![](/img/trans.png)
[英]Mixed-content request from HTTPS page to HTTP (non-HTTPS) localhost address not blocked
[英]"Mixed content blocked" when running an HTTP AJAX operation in an HTTPS page
我有一个要提交给 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 加载了一个页面,并试图通过 AJAX 和 HTTP 中的 API 进行访问。但是浏览器不允许我们这样做。
因此,如果您不能将 API 设置为 HTTPS(这是我的情况),我们仍然可以采用不同的方式来解决这个问题。
主要问题不是混合内容问题,而是我想将数据提交到 API 并将用户重定向到花哨的感谢页面。 我没有使用 AJAX,而是制作了一个 php 文件,该文件接收数据,使用 curl 将其发送到 API(因为这是在服务器端完成的,所以没有混合内容问题),并将我的快乐用户重定向到一个精美的感谢页面。
我通过向 HTML 页面添加以下代码解决了这个问题,因为我们使用的是不受我们控制的第三方 API。
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
希望这会有所帮助,并为记录。
如果您使用 HTTPS 在浏览器中加载页面,浏览器将拒绝通过 HTTP 加载任何资源。 正如您所尝试的那样,将 API URL 更改为使用 HTTPS 而不是 HTTP 通常可以解决此问题。 但是,您的 API 不得允许 HTTPS 连接。 因此,您必须在主页上强制使用 HTTP 或请求它们允许 HTTPS 连接。
请注意:如果您转到 API URL 而不是尝试使用 AJAX 加载它,该请求仍然有效。 这是因为浏览器不是从安全页面中加载资源,而是加载不安全页面并接受它。 但是,为了通过 AJAX 使用它,协议应该匹配。
如果您只是在访问您信任的网页并且想要快速前进,只需:
1- 单击地址栏最右侧的盾牌图标。
2- 在弹出窗口中,单击“仍然加载”或“加载不安全的脚本”(取决于您的 Chrome 版本)。
如果要将 Chrome 浏览器设置为始终(在所有网页中)允许混合内容:
1- 在打开的 Chrome 浏览器中,按键盘上的 Ctrl+Shift+Q 强制关闭 Chrome。 在下一步之前必须完全关闭 Chrome。
2- 右键单击 Google Chrome 桌面图标(或开始菜单链接)。 选择属性。
3- 在目标字段中现有信息的末尾,添加:“--allow-running-insecure-content”(第一个破折号前有一个空格。)
4- 单击确定。
5- 打开 Chrome 并尝试启动之前被阻止的内容。 它现在应该可以工作了。
这个错误的原因很简单。 您的 AJAX 试图通过 HTTP 调用,而您的服务器通过 HTTPS 运行,因此您的服务器拒绝调用您的 AJAX。 这可以通过在主 HTML 文件的 head 标记中添加以下行来解决:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
我在 Vue-CLI 应用程序中遇到了与 Axios 请求相同的问题。 在 Chrome 的网络选项卡中进一步检查时,我发现 axios 的请求 URL 正确具有https
但响应 'location' 标头是http
。
这是由nginx
引起的,我通过将这两行添加到 nginx 的服务器配置来修复它:
server {
...
add_header Strict-Transport-Security "max-age=31536000" always;
add_header Content-Security-Policy upgrade-insecure-requests;
...
}
可能无关紧要,但我的 Vue-CLI 应用程序是在 nginx 的子路径下提供的,配置如下:
location ^~ /admin {
alias /home/user/apps/app_admin/dist;
index index.html;
try_files $uri $uri/ /index.html;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
}
如果您的 API 代码在node.js服务器上运行,那么您需要将注意力集中在那里,而不是在 Apache 或 NGINX 中。 Mikel 是对的,将 API URL 更改为 HTTPS 是答案,但是如果您的 API 正在调用 node.js 服务器,最好设置为 HTTPS! 当然,node.js 服务器可以在任何未使用的端口上,不必是端口 443。
您可以将动态表单与元素一起使用,而不是使用 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()
就我而言,我的 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)
}
我是同样的问题,但对我来说问题是 ng build 命令。 我正在做“ng build --prod”,我已将其更正为“ng build --prod --base-href /applicationname/”。 这解决了我的问题。
这个解决方案对我很好
只需添加到头部
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
我想分享一个对我来说触发混合内容问题的小怪事。 我正在使用 DataTables 并提供一个 AJAX url 看起来像这样:
mypath/ajax_get/'.$clientID
这是在 PHP 中设置的,但并不总是设置$clientID
。 因此,当 Datatables 代码运行时,它只是结束了ajax_get/
。 由于某些未知原因,这足以绕过 https 并尝试加载 http。 我不认为这是一个浏览器错误,因为我在 Chrome 和 Firefox 中尝试过,但如果您遇到问题,我希望这会有所帮助。
与 html/调试一样,如果有疑问,请创建一个重复页面并剥离代码块,直到您可以查明问题所在!
对于本地的 laravel 8 没问题,但在生产中我遇到了问题。 为了解决这个问题,我使用了 POST 方法并在 url 的末尾删除了一个简单的斜杠。 我把它从:
/我的/网址/
到:
/我的/网址
它有效。
我不知道原因。 也许有人可以解释一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.