用户脚本 cross-origin 请求失败
Userscript cross-origin request failing
我的AJAX函数:
function ajaxQuery(url, method, param, async, onsuccess, onfailure) {
var xmlHttpRequest = new XMLHttpRequest();
var callback = function(r) { r.status==200 ? (typeof(onsuccess)=='function' && onsuccess(r)) : (typeof(onfailure)=='function' && onfailure(r)); };
if(async) { xmlHttpRequest.onreadystatechange = function() { if(xmlHttpRequest.readyState==4) { callback(xmlHttpRequest); } } }
xmlHttpRequest.open(method, url, async);
xmlHttpRequest.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest');
xmlHttpRequest.withCredentials = true;
if(method == 'POST') { xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); }
xmlHttpRequest.send(param);
if(!async) { callback(xmlHttpRequest); }
}
函数调用:
ajaxQuery('http://example.net/index.php', 'GET', null, true, function(r) {
tmp.innerHTML = r.responseText;
nlt = [].map.call(tmp.querySelectorAll('.nlt'), function(x) { return x.textContent; });
});
Headers 设置在 PHP:
header('Access-Control-Allow-Origin: https://example.com');
header('Access-Control-Allow-Origin: https://www.example.com');
header('Access-Control-Allow-Origin: http://example.net');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Credentials: true');
if(!preg_match('%https?:\/\/(www\.)?example\.com%', $_SERVER['HTTP_REFERER']) && !preg_match('%https?:\/\/example\.net%', $_SERVER['HTTP_REFERER'])) { die('No way!'); }
我从使用 https 的页面调用用户脚本,而我的域使用 http。当我通过 http 尝试 AJAX 时,我得到 (Firefox) Blocked loading mixed active content
。如果我将查询 URL 切换为 https,错误将更改为 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource
,即使我的 PHP 脚本明确允许来自外部站点的请求。我错过了什么?
在此特定示例中,我的网站是“http://example.net" and the external site is "https://www.example.com”
Access-Control-Allow-Origin header 应该与 Origin header 的值相同,只要您愿意。
所以。你想要多个域。我建议您使用 'regex'
如果协议不匹配,至少在 Firefox 和 Chromium 中,不可能通过 AJAX、JSONP 或 iFrame 获取外部资源,因为愚蠢的“mixed content”限制。我的网站是 运行 over http,并且为其编写用户脚本的网站已强制执行 https(这意味着尝试通过 http 请求其页面会自动重定向到 https,因此我什至无法通过选择来解决限制用于 http)。
我的AJAX函数:
function ajaxQuery(url, method, param, async, onsuccess, onfailure) {
var xmlHttpRequest = new XMLHttpRequest();
var callback = function(r) { r.status==200 ? (typeof(onsuccess)=='function' && onsuccess(r)) : (typeof(onfailure)=='function' && onfailure(r)); };
if(async) { xmlHttpRequest.onreadystatechange = function() { if(xmlHttpRequest.readyState==4) { callback(xmlHttpRequest); } } }
xmlHttpRequest.open(method, url, async);
xmlHttpRequest.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest');
xmlHttpRequest.withCredentials = true;
if(method == 'POST') { xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); }
xmlHttpRequest.send(param);
if(!async) { callback(xmlHttpRequest); }
}
函数调用:
ajaxQuery('http://example.net/index.php', 'GET', null, true, function(r) {
tmp.innerHTML = r.responseText;
nlt = [].map.call(tmp.querySelectorAll('.nlt'), function(x) { return x.textContent; });
});
Headers 设置在 PHP:
header('Access-Control-Allow-Origin: https://example.com');
header('Access-Control-Allow-Origin: https://www.example.com');
header('Access-Control-Allow-Origin: http://example.net');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Credentials: true');
if(!preg_match('%https?:\/\/(www\.)?example\.com%', $_SERVER['HTTP_REFERER']) && !preg_match('%https?:\/\/example\.net%', $_SERVER['HTTP_REFERER'])) { die('No way!'); }
我从使用 https 的页面调用用户脚本,而我的域使用 http。当我通过 http 尝试 AJAX 时,我得到 (Firefox) Blocked loading mixed active content
。如果我将查询 URL 切换为 https,错误将更改为 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource
,即使我的 PHP 脚本明确允许来自外部站点的请求。我错过了什么?
在此特定示例中,我的网站是“http://example.net" and the external site is "https://www.example.com”
Access-Control-Allow-Origin header 应该与 Origin header 的值相同,只要您愿意。
所以。你想要多个域。我建议您使用 'regex'
如果协议不匹配,至少在 Firefox 和 Chromium 中,不可能通过 AJAX、JSONP 或 iFrame 获取外部资源,因为愚蠢的“mixed content”限制。我的网站是 运行 over http,并且为其编写用户脚本的网站已强制执行 https(这意味着尝试通过 http 请求其页面会自动重定向到 https,因此我什至无法通过选择来解决限制用于 http)。