uniapp 如何发送formData数据请求(全网最佳解决方案)

常见的媒体格式类型如下:

  1. text/html : HTML格式

  2. text/plain :纯文本格式      

  3. text/xml :  XML格式

  4. image/gif :gif图片格式    

  5. image/jpeg :jpg图片格式 

  6. image/png:png图片格式

以application开头的媒体格式类型: 

  1. application/xhtml+xml :XHTML格式
  2. application/xml     : XML数据格式
  3. application/atom+xml  :Atom XML聚合格式    
  4. application/json    : JSON数据格式
  5. application/pdf       :pdf格式  
  6. application/msword  : Word文档格式
  7. application/octet-stream : 二进制流数据(如常见的文件下载)
  8. application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
  9.  multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

1.首先想到的就是修改Content-Type

1.1Content-Type: 'application/x-www-form-urlencoded'

uni.request({
        url:URL.TASK_SYNC_VM, //仅为示例,并非真实接口地址。
        data:formData,
        method:"POST",
        header: {
           Authorization,
           'Content-Type': 'application/x-www-form-urlencoded'
       }
   }),

控制台请求格式如下 

 1.2'Content-Type': 'application/json;charset:utf-8'

uni.request({
        url:URL.TASK_SYNC_VM, //仅为示例,并非真实接口地址。
        data:formData,
        method:"POST",
        header: {
           Authorization,
           'Content-Type': 'application/json;charset:utf-8',
       }
   }),

 Content-Type常见的四种类型:

Content-Type的值form表单  Ajax(xhr)
multipart/form-data可以通过enctype属性设置发送的数据形式为FormData时的默认值
application/x-www-form-urlencoded默认。即未设置enctype属性时的默认值可以通过setRequestHeader方法设置
application/json不支持。可以通过enctype属性设置,但提交时会自动转为application/x-www-form-urlencoded可以通过setRequestHeader方法设置
text/plain可以通过enctype属性设置发送的数据形式为字符串时的默认值。包括JSON.Stringify方法返回的json字符串

Content-Type

 2.传递formData类型的数据,使用fly.js

 let formData = new Formdata()
 Object.keys(data).forEach((index) => {
    formData.append(index, data[index])
 })
 console.log(formData.get('userId'));


uni.request({
		url:URL.TASK_SYNC_VM, //仅为示例,并非真实接口地址。
		data:formData, //uni.request 不支持formData类型的数据
		method:"POST",
		header: {
		Authorization,
	    'Content-Type': 'multipart/form-data'
	}
)}

 ps:uni.request 不支持formData类型的数据

 uni.app提供了支持formData类型的数据,但是是传文件的明显不符合我们的需求。

uni.uploadFile({
	url,
	file, // 文件
	name, // 在FormData 中文件对应的属性名
	formData: data, // 除文件外其他所有数据,传对象,会默认转换为 FormData
	header: {
		token
		// 不需要手动指定 multipart/form-data ,本 API 默认 multipart/form-data 
		// 手动指定需要计算 boundary 并拼接上 
	},
	success: res => {
		
	},
})

然后找能支持发送formData类型数据的库 fly.js

目前Fly.js支持的平台包括:Node.js 、微信小程序 、Weex 、React Native 、Quick App 和浏览器,这些平台的 JavaScript 运行时都是不同的

安装fly: 

npm install flyio
let data = {
						'userId': 'a85e5678-419d-4e8f-8da0-c961b4186333',
						'package': 'io.changchun.app',
						'taskId': 1,
						'taskName': 'test2',
						// "injectObject":'{"url":"/pages/myMission/myMission"}'
					}
					let formData = new Formdata()
					Object.keys(data).forEach((index) => {
						formData.append(index, data[index])
					})

fly.post(URL.TASK_SYNC_VM,{...formData},{headers:{
						Authorization,
					    "content-type":"multipart/form-data"
					}})

运行项目到浏览器 我们看到能正常发送formData类型请求

fly.js的二次封装请参考:fly.js 的二次封装_流氓也是种气质 _Cookie的博客-CSDN博客

 我们接下来我们运行到真机上会遇到以下提示:FormData is not defined

用为App的js运行在jscore下而不是浏览器里,没有浏览器专用的js对象,比如document、xmlhttp、cookie、window、location、navigator、localstorage、websql、indexdb、webgl等对象。

FormData也是浏览器定制的对象,uniapp非H5端不支持

3.解决app不支持FormData对象的问题,我们使用renderjs

 3.1 、renderjs的作用是什么?

renderjs 主要服务于APP,因为uni-app为vue+js+html进行编写,整个是h5的技术栈。而app上并没有document等基础对象。那么,涉及到这些的前端类库就无法使用,例如html2、canvas、canvas2、image。而要用这些怎么办,这是用就出现了renderjs这种视图层工具来进行渲染。

运行在视图层的js

大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力(减少通讯损耗提升性能,例如一些手势或canvas动画的场景)

在视图层操作dom,运行for web的js库(可以操作dom,意味着拥有window、document等这些全局变量,在app-vue的service层没有这些)

详细语法使用可以参考以下文章:uniapp中使用renderjs_流氓也是种气质 _Cookie的博客-CSDN博客

3.2 由于我们要避免new FormData,但是我们又要使用FormData类型数据发送请求故使用axios 配合renderjs,满足我们在H5和app端都能使用

<view class="nav_title" @click="custom.taskSycn">test</view> 
// 注意renderjs方法的调用custom.taskSycn() 不能加(),在H5能正常解析,但是在APP端无法正常解析

<script module="custom" lang="renderjs"> // 定义renderjs 即视图层,这里面的语法及生命周期都和vue语法保持一致
	import axios from 'axios'
	export default {
		data() {
			return {}
		},
		methods: {
			handleClick() {
				console.log('9999');
			},
			taskSycn() {
				console.log('taskSycn++++');
			                  let Authorization = `9j8yMV b964c9635dcf5e0f9c50a6073bdb69d7`
			                  let data = {
			                    userId: "a85e5678-419d-4e8f-8da0-c961b4186333",
			                    package: "io.changchun.app",
			                    taskId: 1,
			                    taskName: "test21"
			                    // "injectObject":'{"url":"/pages/myMission/myMission"}'
			                  };
			                  axios
			                    .post("http://116.141.0.158:8083/mobile-portal/task/sync.vm", {
			                      ...data
			                    }, {
			                      headers: {
			                        Authorization,
			                        "Content-type": "multipart/form-data"
			                      }
			                    })
			                    .then(function (response) {
			                      console.log(response);
			                    })
			                    .catch(function (error) {
			                      console.log(error);
			                    });
			                }
		}
	}
</script>

<script>  // 就是我们正常的uniapp js代码  即service层
export default { 
		data() {
			return {}
		},
}
</script>

### 解决方案 在 Vue.js 开发过程中,如果遇到 `ReferenceError: FormData is not defined` 的错误提示,通常是因为浏览器环境不支持 `FormData` 对象或者代码运行环境中缺少必要的 polyfill 支持[^1]。 以下是具体的解决方案: #### 1. 确认浏览器兼容性 `FormData` 是 HTML5 提供的一个内置对象,用于创建键值对集合以便通过 HTTP 请求发送表单数据。部分老旧浏览器可能不支持该功能。因此,在使用前需确认目标用户的浏览器是否支持此特性[^2]。 可以通过以下方式检测当前环境是否支持 `FormData`: ```javascript if (window.FormData) { console.log('当前环境支持 FormData'); } else { console.error('当前环境不支持 FormData'); } ``` #### 2. 添加 Polyfill 支持 对于不支持 `FormData` 的旧版浏览器,可以引入第三方库或手动实现一个简单的替代方法来模拟其行为。推荐的方式是加载 [formdata-polyfill](https://github.com/jimmywarting/FormData) 库作为补丁文件[^3]。 安装命令如下: ```bash npm install formdata-polyfill --save ``` 随后在项目入口处(如 main.js 或 app.js)全局引入它: ```javascript import 'formdata-polyfill'; ``` 这样即使是在较老版本的 IE 浏览器下也能正常工作[^4]。 #### 3. 正确初始化并操作 FormData 实例 确保在组件的方法内部始终以标准形式调用 `new FormData()` 构造函数实例化新的表单数据容器,并且记得绑定到正确的上下文中去访问其他成员变量比如计数器属性等[^5]: 修改后的代码示例如下所示: ```html <div id="box"> <button @click="submitForm">提交</button> <input type="file" ref="uploadFile"/> </div> <script type="text/javascript"> var vm = new Vue({ el: '#box', methods: { submitForm() { const formData = new FormData(); // 创建一个新的 FormData 对象 if(this.$refs.uploadFile.files.length === 0){ alert("请选择要上传的文件!"); return; } formData.append('uploaded_file', this.$refs.uploadFile.files[0]); fetch('/api/upload',{ method:'POST', body:formData, }).then(response => response.json()) .then(result=>console.log(result)) .catch(error=>console.error('There was a problem with the fetch operation:', error)); }, } }); </script> ``` 以上调整不仅解决了原始问题中的引用错误情况,还增加了实际应用场景下的文件上传逻辑处理流程[^6]。 --- ###
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流氓也是种气质 _Cookie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值