uniapp开发安卓App出现的问题

248 阅读4分钟

最近开发安卓项目,应要求搭建一个安卓框架,使用的是uniapp开发,但是在搭建的过程中出现了很多问题,其中最大的问题就是在浏览器里面运行项目,是可以通过接口获取到数据并且渲染上去的,一旦转移到安卓真机调试,就会发现,接口的数据渲染不上去,百度了很多很久,最终还是没能从百度找到原因 这是代码

image.png

image.png

image.png

image.png

最后仍然是在百度上找不到解决方案,偶然在hbuilder中的控制台看到可以debugger的程序,

image.png

于是在接口请求那里做了一个debugger,最后才发现。

image.png App端是不需要进行跨域请求配置的,只需要进行正确的BaseUrl地址配置和正常的请求就可以了。发现了问题的根本原因后,最终又去更改了我的request.conf文件。

image.png

最后 附上我的请求配置文件

conf.js文件  这个文件用来给下面的uni.interface.js和uview.interface.js文件使用
module.exports = {
	//是否开发模式
	IS_DEV: true,
	// 开发环境地址
	// DEV_URL: "/api",  
	DEV_URL: "http://192.188.88.188:8080",
	// 生产环境地址
	PRO_URL: "正式地址",
	//请求超时时间
	TIMEOUT: 60000,
	//是否开启请求日志
	REQUEST_LOG: false,
	//是否开启请求异常提示
	CATCH_MESS: false,
	//请求时提示文字
	LOADING_TEXT: '正在加载',
	//是否需要签名
	IS_SECRET: false,
	//签名字符串
	APP_SECRET: "uniapp!@#2022",
};



这是uniapp官方提供的request请求封装
uni.interface.js文件,这个文件类似使用axios来封装请求






/**
 * 通用uni-app网络请求
 * 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
 */
import setting from "./config.js";

export default {
	config: {
		baseURL: setting.IS_DEV ? setting.DEV_URL : setting.PRO_URL,
		header: {
			'Content-Type': 'application/json;charset=UTF-8',
			// 'Content-Type': 'application/x-www-form-urlencoded',
		},
		// header: {},
		custom: {
			// 请求接口展示Loading
			ShowLoading: true,
			// Loading中是否遮罩
			LoadingMask: true,
			// Loading文本
			LoadingText: setting.LOADING_TEXT,
		},
		dataType: "json",
		/* 如设为json,会对返回的数据做一次 JSON.parse */
		responseType: "text",
		// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
		timeout: setting.TIMEOUT,
		// #endif
		// #ifdef APP-PLUS
		// 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
		sslVerify: true,
		// #endif
		// #ifdef H5
		// 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
		withCredentials: false,
		// #endif
		// #ifdef APP-PLUS
		// DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
		firstIpv4: false,
		// #endif
	},
	get(url, data, options) {
		if (!options) {
			options = {}
		}
		options.url = url
		options.data = data
		options.method = 'GET'
		return this.request(options)
	},
	post(url, data, options) {
		if (!options) {
			options = {}
		}
		options.url = url
		options.data = data
		options.method = 'POST'
		return this.request(options)
	},
	request(options) {
		console.log('uni')
		//请求前处理,相当于请求拦截
		let config = Object.assign(this.config, options); //合并全局配置及局部配置项
		//加载提示
		if (config.custom.ShowLoading) {
			uni.showLoading({
				title: config.custom.LoadingText || '正在加载',
				mask: config.custom.LoadingMask || false
			});
		}
		config.url = config.baseURL + config.url
		console.log(config.url, "请求的url")
		config.data = config.data || {}

		//如果token不为空则请求时携带token
		let _token = uni.getStorageSync('token') || ''
		if (_token != '' && _token != undefined) {
			config.data['token'] = _token
		}
		config.data['timestamp'] = Math.round(new Date() / 1000); //时间戳;

		//是否开启请求日志
		if (setting.REQUEST_LOG) {
			_reqlog(config)
		}
		return new Promise((resolve, reject) => {
			uni.request(config).then(data => {
				// data为一个数组
				// 数组第一项为错误信息 即为 fail 回调
				// 第二项为返回数据
				var [err, res] = data;

				//结束loading提示
				if (config.custom.ShowLoading) {
					uni.hideLoading();
				}
				//是否开启响应日志
				if (setting.REQUEST_LOG) {
					_reslog(res)
				}
				//如果第一项不为空,则表示请求失败fail
				if (err != null && err != undefined && err != '') {
					//错误处理
					console.log(err)
					reject(err)
				} else {
					//请求成功,状态码200
					if (res.statusCode == 200) {
						let result = res.data;
						// if 与后台规定code代码进行处理数据返回
						if (result.code == 0) { //后台约定code1为请求成功
							resolve(result.data)
						} else if (result.code == 2) { //后台约定code2为用户被锁定
							uni.showToast({
								title: result.msg,
								icon: 'none'
							});
							//转入登录页
							setTimeout(function() {
								uni.navigateTo({
									url: '/pages/login/login'
								})
							}, 1000);
						} else {
							uni.showToast({
								title: result.msg,
								icon: 'none'
							})
						}
					} else {
						//状态码不是200
						uni.showToast({
							title: res.statusCode,
							icon: 'none'
						});
					}
				}
			});
		})
	},
}
/**
 * 请求接口日志记录
 */
//请求日志
function _reqlog(req) {
	console.log("请求地址:" + req.url)
	console.log("请求参数:" + JSON.stringify(req.data))
}
//响应日志
function _reslog(res) {
	console.log("响应结果:" + JSON.stringify(res))
}



这是uview官方提供的请求封装,两者都实现了请求拦截和响应拦截


import setting from "./config.js";

const install = (Vue, vm) => {
	// 初始化请求配置

	uni.$u.http.setConfig((config) => {
		// 域名设置
		config.baseURL = setting.IS_DEV ? setting.DEV_URL : setting.PRO_URL;
		config.header = {
			'Content-Type': 'application/json;charset=UTF-8',
			// 'Content-Type':'application/x-www-form-urlencoded'
		};
		// 设置为json,返回后会对数据进行一次JSON.parse()
		config.dataType = 'json';
		config.responseType = 'text';
		// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
		config.custom = {
			// 请求接口展示Loading
			ShowLoading: true,
			// Loading中是否遮罩
			LoadingMask: true,
			// Loading文本
			LoadingText: setting.LOADING_TEXT,
		}; // 全局自定义参数默认值
		// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
		config.timeout = setting.TIMEOUT;
		// #endif
		// #ifdef APP-PLUS
		// 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
		config.sslVerify = false;
		// #endif
		// #ifdef H5
		// 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
		config.withCredentials = false;
		// #endif
		// #ifdef APP-PLUS
		// DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
		config.firstIpv4 = true;
		// #endif
		// 全局自定义验证器。参数为statusCode 且必存在,不用判断空情况。
		config.validateStatus = (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
			return statusCode >= 200 && statusCode < 300
		};
		return config;
	});

	// 请求拦截部分,如配置,每次请求前都会执行
	uni.$u.http.interceptors.request.use((config) => {
		console.log('uveiw')
		if (config.custom.ShowLoading) {
			uni.showLoading({
				title: config.custom.LoadingText || '正在加载',
				mask: config.custom.LoadingMask || false
			});
		}
		config.data = config.data || {}

		let _token = uni.getStorageSync('token') || ''

		if (_token != '' && _token != undefined) {
			config.data['token'] = _token
		}
		config.data['timestamp'] = Math.round(new Date() / 1000); //时间戳;
		// 引用token
		// 方式一,存放在vuex的token,假设使用了uView封装的vuex方式
		// 见:https://uviewui.com/components/globalVariable.html
		// config.header.token = vm.token;

		// 方式二,如果没有使用uView封装的vuex方法,那么需要使用$store.state获取
		// config.header.token = vm.$store.state.token;

		// 方式三,如果token放在了globalData,通过getApp().globalData获取
		// config.header.token = getApp().globalData.username;

		// 方式四,如果token放在了Storage本地存储中,拦截是每次请求都执行的
		// 所以哪怕您重新登录修改了Storage,下一次的请求将会是最新值
		// const token = uni.getStorageSync('token');
		// config.header.token = token;
		//config.header.Token = 'xxxxxx';

		// 可以对某个url进行特别处理,此url参数为this.$u.get(url)中的url值
		//if (config.url == '/user/login') config.header.noToken = true;

		//是否开启请求日志
		if (setting.REQUEST_LOG) {
			_reqlog(config)
		}
		// 最后需要将config进行return
		return config;

	}, config => {
		uni.hideLoading();
		if (setting.CATCH_MESS) {
			vm.$u.toast("请求时异常");
		}
		return Promise.reject(config)
	})

	// 响应拦截,如配置,每次请求结束都会执行本方法
	uni.$u.http.interceptors.response.use((res) => {
		if (res.config.custom.ShowLoading) {
			uni.hideLoading();
		}
		//响应日志
		if (setting.REQUEST_LOG) {
			_reslog(res)
		}
		// if 状态码是否正常
		if (res.statusCode == 200) {
			let result = res.data;
			// if 与后台规定code代码进行处理数据返回
			if (result.code == 0) { //后台约定code1为请求成功
				return result.data;
			} else if (result.code == 2) {
				//后台约定code2为用户被锁定
				vm.$u.toast(result.msg);
				setTimeout(function() {
					uni.navigateTo({
						url: '/pages/login/login'
					})
				}, 1000);
			} else {
				vm.$u.toast(result.msg);
			}
		} else {
			vm.$u.toast(res.statusCode);
		}
		return false;
	}, (response) => {
		uni.hideLoading();

		if (setting.CATCH_MESS) {
			vm.$u.toast("响应时异常!");
		}
		// 将这个提示注释掉,不然请求接口不成功的就会提示一个undefined
		// vm.$u.toast(response.data.msg);
		return Promise.reject(response)

	});
}
//请求日志
function _reqlog(req) {
	console.log("请求地址:" + req.baseURL + req.url)
	console.log("请求参数:" + JSON.stringify(req.data))
}
//响应日志
function _reslog(res) {
	console.log("响应结果:" + JSON.stringify(res))
}
export default {
	install
}

我的目录结构

image.png

如果要使用的话,就直接映入这两个文件其中的一个

//如果用uni请求
// import request from '@/common/uni.interface.js';

//如果是用uview请求,就用下面这句
const request = uni.$u.http


//获取用户信息
export function getUserInfo(params) {
	return request.get('/api/userinfo', params)
}

//用户登录
export function userLogin(params) {
	return request.post('/api/login', params)
}

export function getList(data) {
	return request.post('/cr200j_integration_system/duty/query_duty', data)
}
//更改配置项,阻止loading提示
// export function getUserInfo(params){
// 	return request.post('api/login', {custom:{ShowLoading:false}})
// }

image.png