我正在开发一个使用jQuery(或其他库/依赖项)的Web项目,因此我尝试复制jQuery用来发出AJAX请求的代码。该项目之前使用过jQuery,因此我将$ .ajax()方法的替换结构化为具有相同的行为,但是我不能让我做出跨域请求。例如,在尝试加载脚本时,我在控制台中收到此错误。
XMLHttpRequest cannot load <URL>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin <URL> is therefore not allowed access.
我熟悉CORS和整个跨域安全策略以及它需要什么,但我感到困惑的是jQuery如何绕过它,而我的代码却不能。我认为jQuery必须有一些特殊的东西吗?
这就是我的$ .ajax()替换函数目前的脚本编写方式。
function ajax (options) {
var request = new XMLHttpRequest();
if ("withCredentials" in request)
request.withCredentials = false;
else if (typeof XDomainRequest !== "undefined")
var request = new XDomainRequest();
options.type = options.type || options.method || "GET";
request.open(options.type.toUpperCase(), options.url, true);
for (var i in options.headers) {
request.setRequestHeader(i, options.headers[i]);
}
if (typeof options.beforeSend == "function")
var go = options.beforeSend(request, options);
if (go == false)
return false;
request.onreadystatechange = function () {
if (this.readyState === XMLHttpRequest.DONE) {
var resp = this.responseText;
try {
var body = JSON.parse(resp);
this.responseJSON = body;
}
catch (err) {
var body = resp;
}
if (this.status < 300 && typeof options.success == "function")
options.success(body, this.status, this);
else if (typeof options.error == "function")
options.error(this, this.status, body);
if (typeof options.complete == "function")
options.complete(this, this.status);
}
};
if (typeof options.data == "object" && options.data !== null)
options.data = JSON.stringify(options.data);
if (options.type.toUpperCase() != "GET")
request.send(typeof options.data !== "undefined" ? options.data : null);
else
request.send();
return request;
}
有人可以指出我是否遗漏了明显的东西?我是否需要在飞行前或其他地方手动执行OPTIONS?
答案 0 :(得分:0)
我找到了解决方法。问题似乎源于尝试专门加载跨域脚本。 jQuery使用$ .getScript()来实现这一点,实际上只是向页面添加了一个脚本而不是发出跨域HTTP请求。
我使用此代码替代该功能。
function getScript (url, callback) {
var loadScript = function (url, callback) {
var scrpt = document.createElement("script");
scrpt.setAttribute("type", "text/javascript");
scrpt.src = url;
scrpt.onload = function () {
scrpt.parentNode.removeChild(scrpt);
console.log("Script is ready, firing callback!");
if (callback)
callback();
};
document.body.appendChild(scrpt);
}
var isReady = setInterval(function () {
console.log(document.body);
if (document.body) {
clearInterval(isReady);
loadScript(url, callback);
}
}, 25);
}