You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为XMLHttpRequest添加beforeSend函数时遇TypeError错误求助

解决XMLHttpRequest自定义beforeSend时的TypeError: Cannot read property 'type' of undefined问题

看起来你是想把jQuery Ajax里的beforeSend逻辑搬到原生XMLHttpRequest上,但碰到了参数未定义的错误,我来帮你理清楚问题和解决办法。

错误原因分析

这个报错直接说明你在beforeSend函数里访问settings.type时,settings参数是undefined——也就是说,你调用beforeSend的时候,并没有正确传递第二个包含请求方法的settings对象。

jQuery的beforeSend钩子会自动传入xhr和settings(包含请求方法、URL等配置),但原生XMLHttpRequest并没有内置这个钩子机制,所以你得自己处理参数传递或者封装XHR逻辑。

解决方案

这里提供两种可行的处理方式,根据你的使用场景选择:

方式1:手动传递settings参数

如果你只是偶尔使用原生XHR,不想封装工具函数,可以在调用beforeSend时,手动把请求方法等信息作为settings传进去:

var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

function beforeSend(xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !settings.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
}

// 原生XHR使用示例
var xhr = new XMLHttpRequest();
var requestMethod = 'POST';
var requestUrl = '/your-api-endpoint/';

// 调用beforeSend时,手动传入settings对象
beforeSend(xhr, { 
    type: requestMethod, 
    crossDomain: false // 根据你的实际跨域情况调整
});

xhr.open(requestMethod, requestUrl, true);
xhr.send();

方式2:封装类似jQuery Ajax的XHR工具

如果需要频繁使用带beforeSend的XHR,可以封装一个工具函数,自动处理参数传递和钩子调用,更贴近jQuery的使用体验:

var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

// 封装带beforeSend的XHR工具
function ajax(options) {
    var xhr = new XMLHttpRequest();
    var method = (options.method || 'GET').toUpperCase();
    var settings = {
        type: method,
        crossDomain: options.crossDomain || false,
        url: options.url
    };

    // 执行beforeSend钩子(如果配置了)
    if (typeof options.beforeSend === 'function') {
        // 把xhr和settings传给beforeSend
        options.beforeSend(xhr, settings);
    }

    // 自动处理CSRF头(也可以放在beforeSend里)
    if (!csrfSafeMethod(method) && !settings.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }

    // 处理成功/失败回调
    xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
            options.success && options.success(xhr.responseText, xhr);
        } else {
            options.error && options.error(xhr.statusText, xhr);
        }
    };

    xhr.onerror = function() {
        options.error && options.error('Network error', xhr);
    };

    xhr.open(method, settings.url, true);
    xhr.send(options.data || null);

    return xhr;
}

// 使用示例
ajax({
    method: 'POST',
    url: '/your-api-endpoint/',
    beforeSend: function(xhr, settings) {
        console.log('即将发送请求,方法:', settings.type);
        // 这里可以添加自定义请求头、加载动画等逻辑
    },
    success: function(response, xhr) {
        console.log('请求成功:', response);
    },
    error: function(error, xhr) {
        console.error('请求失败:', error);
    }
});

关键注意点

  • 原生XHR没有自动传入settings的机制,必须显式传递或者自己封装;
  • 确保settings.type对应的是请求的HTTP方法(大写/小写要和csrfSafeMethod的正则匹配一致,建议统一转成大写);
  • 如果涉及跨域请求,记得调整crossDomain参数的取值。

内容的提问来源于stack exchange,提问作者Hannan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:26:31