使用 JsonP 的 JavaScript XMLHttpRequest

IT技术 javascript ajax jsonp
2021-02-06 13:47:05

我想将请求参数发送到其他域

我已经知道交叉脚本需要 JsonP 并且我已经将 JsonP 与 Jquery ajax 一起使用

但我不知道如何使用 XMLHttpRequest 进行跨脚本编写

以下代码是我的基本 XMLHttpRequest 代码。

我想我需要改变xhr.setRequestHeader(),我必须添加解析代码

请给我任何想法

var xhr;
function createXMLHttpRequest(){    
    if(window.AtiveXObject){
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        xhr = new XMLHttpRequest();
    }   
    var url = "http://www.helloword.com";   
}

function openRequest(){ 
    createXMLHttpRequest();
    xhr.onreadystatechange = getdata;
    xhr.open("POST",url,true);
    xhr.setRequestHeader("Content-Type",'application/x-www-form-urlencoded');
    xhr.send(data); 
}

function getdata(){
    if(xhr.readyState==4){
        if(xhr.status==200){
            var txt = xhr.responseText;
            alert(txt);
        }
    }   
}
5个回答

JSONP 不使用 XMLHttpRequests。

使用 JSONP 的原因是为了克服 XHR 的跨域限制。

相反,数据是通过脚本检索的。

function jsonp(url, callback) {
    var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
    window[callbackName] = function(data) {
        delete window[callbackName];
        document.body.removeChild(script);
        callback(data);
    };

    var script = document.createElement('script');
    script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
    document.body.appendChild(script);
}

jsonp('http://www.helloword.com', function(data) {
   alert(data);
});

为简单起见,这不包括请求失败时的错误处理。script.onerror如果需要,请使用

@RyanDay,因为可以使用不同的 url 等调用 jsonp()。
2021-03-17 13:47:05
@Paul Drapper 你能在这里帮助我吗,stackoverflow.com/ questions/36302891/...如果可以,谢谢
2021-03-19 13:47:05
为什么每次都创建一个新的回调名称?
2021-03-22 13:47:05
@ Paul Draper:我的回调没有受到影响。请看我的代码:function pingUrlUsingJSONP(url, callback,onLoad,onError) { var tempCallback = 'jsonp_callback_' + Math.round(100000 * Math.random()); 窗口[tempCallback] = 函数(数据){ 删除窗口[tempCallback]; document.body.removeChild(script);callback(data); }; var script = document.createElement('script'); script.type = 'text/html';script.onerror = onError; script.onload = onLoad;script.async = true; script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + tempCallback; document.body.appendChild(script); }
2021-04-03 13:47:05

我知道你已经得到了答案,但是如果这里的其他人想要一个使用 Promise 的例子,这里是一个。

function jsonp(url) {
    return new Promise(function(resolve, reject) {
        let script = document.createElement('script')
        const name = "_jsonp_" + Math.round(100000 * Math.random());
        //url formatting
        if (url.match(/\?/)) url += "&callback="+name
        else url += "?callback="+name
        script.src = url;

        window[name] = function(data) {
            resolve(data);
            document.body.removeChild(script);
            delete window[name];
        }
        document.body.appendChild(script);
    });
}
var data = jsonp("https://www.google.com");
data.then((res) => {
    console.log(res);
});
尝试运行您的代码。它不起作用,因为 google.com 不返回 JSONP(至少,不是在那个 URL)
2021-04-10 13:47:05
function JsonpHttpRequest(url, callback) {
    var e = document.createElement('script');
    e.src = url;
    document.body.appendChild(script); // fyi remove this element later /assign temp class ..then .remove it later
    //insetead of this you may also create function with  callback value and  use it instead
    window[callback] = (data) => {
        console.log(data);  // heres you data
    }
}
// heres how to use
function HowTouse(params) {
    JsonpHttpRequest("http://localhost:50702/api/values/Getm?num=19&callback=www", "www")
}

对于 google api,我被迫向 url添加callbackv=1.0参数。如果没有V = 1.0的参数,我得到CORB错误(我的版本以及其他答案代码-但是jQuery的$.ajaxdataType: "jsonp"加这个参数-所以我添加它也开始工作)

跨域读取阻止 (CORB) 阻止了跨域响应https://ajax.googleapis.com/ajax/services/feed/load?callback=jsonp1555427800677使用 MIME 类型 text/javascript。有关更多详细信息,请参阅https://www.chromestatus.com/feature/5629709824032768

以下是我的解决方案的Promise版本

function jsonp(url) {
  return new Promise(function(resolve, reject) {
    var s = document.createElement('script');
    var f="jsonp"+(+new Date()), b=document.body;
    window[f] = d=>{ delete window[f]; b.removeChild(s); resolve(d); };
    s.src=`${url}${url.includes('?')?'&':'?'}callback=${f}&v=1.0`;
    b.appendChild(s);
  })
}

async function send() {
    let r = await jsonp("http://ajax.googleapis.com/ajax/services/feed/load");
    console.log(r);
}
<button onclick="send()">Send JSONP</button>

你不能使用 XMLHttpRequest 做跨域脚本。如果你想在没有 Jquery 的情况下跨域,你必须创建一个新的脚本节点并设置它的 src 属性。

“您不能使用 XMLHttpRequest 进行交叉脚本”— 不正确。“如果你想在没有 Jquery 的情况下跨域”——jQuery 无关紧要,它是一个库,它可以做任何你自己做不到的事情。“您必须创建一个新的脚本节点并设置它的 src 属性”— 不正确,还有其他方法可以发出跨源请求。此外,这只是您如何发出 JSONP 请求的最后三分之一,您还没有解决定义函数或设置回调参数的问题。
2021-03-16 13:47:05
你知道jQuery是如何实现跨域请求的吗?如何通过XMLHttpRequest进行跨域请求?Jsonp和XMLHttpRequest没有关系
2021-03-25 13:47:05
jQuery 至少有三种不同的方式来发出跨域请求。使用 XHR 发出跨域请求的方法在我将其标记为重复的问题中有所描述。
2021-04-10 13:47:05