Jquery-Ajax-“Uncaught TypeError: Illegal invocation”错误

本文详细解析了使用Ajax发送FormData对象时遇到的问题及解决方案,强调了processData和contentType参数的正确配置,避免【TypeError: Illegal invocation】错误。

先看下ajax请求:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>

	<body>
	</body>
	<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
	<script>
		var fd = new FormData();
		fd.append("name", "wang");		
		$.ajax({
			url: 'http://localhost:8080/test',
			type: 'POST',
			data:fd,
			//processData:false
		});
	</script>

</html>

此时ajax请求并不成功,会报【TypeError: Illegal invocation】错误
在这里插入图片描述
再看下Jquery关于Ajax方法的doc文档关于processDatacontentType 参数解释,

processData (default: true)
Type: Boolean
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.

大意是:默认情况下将传给data参数的值作为对象解析并作为请求参数,适合content-type:application/x-www-form-urlencoded的情况;默认是true,如果不想让Jquery处理数据,应该设置值为false。

contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')
Type: Boolean or String
When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header. Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.

contentType默认值是【application/x-www-form-urlencoded; charset=UTF-8】,该值可以是boolean或String,如果是传输的数据对象是FormData,应该设置为false,所以传输FormData,ajax正确设置:

var fd = new FormData();
fd.append("name", "wang");
fd.append("age", 18);
var content = '<a id="a"><b id="b">hey!</b></a>'; 
var blob = new Blob([content], { type: "text/xml"});
fd.append("webmasterfile", blob);
$.ajax({
	url: 'http://localhost:8080/test',
	type: 'POST',
	contentType:false,
	data:fd,
	processData:false
});

参考:

http://api.jquery.com/jQuery.ajax/

<think>我们正在处理一个JavaScript错误:"jquery-1.9.1.min.js:5 Uncaught TypeError: Illegal invocation"。这个错误通常发生在使用jQuery的$.ajax方法时,传入的数据格式不正确或者某些参数不合法。 根据提供的引用信息,我们可以分析错误原因: 1. 引用[1]和引用[3]都提到了在$.ajax调用时出现了相同的错误,引用[1]中提到了调用堆栈,引用[3]则说明了从原生ajax转向jQuery ajax时出现了问题。 2. 引用[2]提到一个类似的错误是由于构造函数调用方式改变导致的(版本升级后构造函数名称变化),但这个问题与我们的情况不完全相同,因为我们遇到的是$.ajax调用的问题。 3. 引用[4]提供了一个具体的例子:在使用FormData对象并通过$.ajax上传文件时,如果设置不当(特别是contentType和processData)会导致这个错误。 综合以上,最常见的导致“Illegal invocation错误的原因是: - 当使用FormData对象时,没有正确设置ajax选项:必须设置`contentType: false`和`processData: false`。 - 传递给ajax的data参数不是一个普通的对象、字符串或者FormData对象,而是一个函数或者不可序列化的值。 因此,解决步骤可以如下: 1. **检查data参数**:确保传递给ajax的data参数是合适的类型(对象、字符串或FormData)。如果使用FormData,必须设置`processData: false`,因为jQuery默认会对数据进行处理(转换为查询字符串),而FormData对象不能被这样处理。同时,设置`contentType: false`,让浏览器自动设置Content-Type为multipart/form-data,并带上正确的边界。 2. **检查其他参数**:确保url是一个字符串,其他选项(如type, dataType等)都是合法的。 3. **检查jQuery版本**:虽然错误发生在1.9.1版本,但确保没有与其他版本的jQuery冲突。 4. **查看调用堆栈**:根据错误信息中的行号(jquery-1.9.1.min.js:5),可以尝试查看非压缩版的jQuery代码,找到对应行,了解具体是哪个函数调用出错。 5. **简化测试**:尝试简化ajax调用,比如只发送一个简单的对象,逐步排除问题。 根据引用[4]中的正确代码示例,我们可以参考其设置来处理FormData的上传。 示例代码(正确使用FormData): ```javascript var formData = new FormData($("#formId")[0]); // 注意:这里获取了DOM元素中的表单 $.ajax({ url: 'your-url', type: 'POST', data: formData, contentType: false, // 必须 processData: false, // 必须 success: function(response) { // 处理成功 }, error: function(xhr, status, error) { // 处理错误 } }); ``` 如果你的情况不是上传文件,而是普通的数据,那么确保传递的数据是一个普通的对象,例如: ```javascript $.ajax({ url: 'your-url', type: 'POST', data: { key1: 'value1', key2: 'value2' }, // 不需要设置contentType和processData为false,除非有特殊情况 // 默认contentType为'application/x-www-form-urlencoded; charset=UTF-8' // 默认processData为true,jQuery会将数据对象转换为查询字符串 success: function(response) { /* ... */ } }); ``` 如果以上方法不能解决问题,请检查是否有其他代码干扰,或者尝试更新jQuery版本(注意兼容性)。 相关问题: 1. 为什么在使用FormData上传文件时需要设置contentType和processData选项? 2. jQuery的$.ajax方法中,data参数可以接受哪些类型的数据? 3. 如何调试jQuery中的“Illegal invocation错误? </think>### 解决 jQuery Ajax "Illegal invocation" 错误的方法 当调用包含 `$.ajax` 的方法时出现 `jquery-1.9.1.min.js:5 Uncaught TypeError: Illegal invocation` 错误,通常是由于以下原因导致: #### 根本原因分析 1. **数据格式不正确**(最常见原因) - 当使用 `FormData` 对象时未正确配置 Ajax 选项 - 传递了无法序列化的数据类型(如函数、循环引用对象等) 2. **特殊参数处理不当** - 未禁用 jQuery 的默认数据处理机制(需设置 `processData: false`) - 未正确设置内容类型(需设置 `contentType: false`) --- ### 解决方案(分步骤) #### 1. 正确使用 FormData 对象(文件上传场景) ```javascript $("#yourForm").submit(function(e) { e.preventDefault(); // 创建 FormData 对象 var formData = new FormData(this); // 关键步骤:直接传递 DOM 表单元素 $.ajax({ url: "your-api-endpoint", type: "POST", data: formData, // 传递 FormData 对象 contentType: false, // 必须设置为 false processData: false, // 必须设置为 false success: function(response) { console.log("上传成功", response); }, error: function(xhr) { console.error("错误代码:", xhr.status); } }); }); ``` #### 2. 普通 AJAX 请求的修复方案 ```javascript $.ajax({ url: "your-api-endpoint", method: "POST", data: JSON.stringify({ // 显式序列化复杂数据 user: "John", items: [1, 2, 3] }), contentType: "application/json", // 明确声明数据格式 processData: false, // 禁用默认处理 success: function(data) { // 处理响应 } }); ``` #### 3. 兼容性检查(针对旧版本 jQuery) ```javascript // 检查 jQuery 版本 console.log("jQuery version:", $.fn.jquery); // 若版本低于 3.0,需显式转换 FormData if (parseFloat($.fn.jquery) < 3.0) { var form = $("#yourForm")[0]; // 获取原生 DOM 元素 var formData = new FormData(form); } ``` --- ### 关键配置说明 | 参数 | 推荐值 | 作用说明 | |------------------|--------------|--------------------------------------------------------------------------| | `contentType` | `false` | 禁止 jQuery 设置默认 Content-Type,让浏览器自动生成正确的 multipart 边界 | | `processData` | `false` | 阻止 jQuery 将 FormData 转换为字符串(会破坏二进制数据) | | `cache` | `false` | 禁用缓存避免陈旧数据干扰(可选) | | `dataType` | `'json'` | 明确期待返回 JSON 格式 | --- ### 调试建议 1. **控制台检查** 在发送请求前打印数据: ```javascript console.log("Data type:", typeof formData); console.log("Is FormData?", formData instanceof FormData); ``` 2. **网络面板分析** - 在 Chrome DevTools 的 Network 标签查看请求负载 - 确认 Content-Type 是否包含 `multipart/form-data` 3. **简化重现** 创建最小测试用例排除其他插件干扰: ```javascript // 最小化测试代码 $.ajax({ url: '/echo/json/', data: new FormData(), contentType: false, processData: false, method: 'POST' }); ``` --- ### 可能触发的其他场景 1. **第三方插件冲突** 检查报错堆栈中是否有 `jquery.hiAlerts-min.js` 等第三方插件,尝试: - 更新插件到最新版 -AJAX 调用前禁用插件 2. **过时 jQuery 方法** 如使用 `$.param()` 序列化 FormData 会触发错误: ```javascript // 错误示例(会引起 Illegal invocation) var data = $.param(new FormData()); ``` --- ### 相关问题 1. 为什么使用 FormData 时必须设置 `processData: false`?[^4] 2. 如何在不支持 FormData 的旧浏览器中实现文件上传? 3. jQuery Ajax 请求中 `contentType` 和 `dataType` 参数有什么区别? 4. 除了 "Illegal invocation",常见的 jQuery Ajax 错误还有哪些解决方法? [^1]: 当传递无法序列化的数据或错误使用 FormData 时会触发类型错误 [^2]: 构造函数调用错误也可能导致类似异常 [^3]: 原生 AJAXjQuery 实现时需注意参数差异 [^4]: FormData 需要特殊处理以避免数据转换破坏
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值