通过调用萤石云的获取设备列表功能,我们可以根据 ACCESS_TOKEN
获取该用户下的设备列表。
Python 调用接口
根据接口文档[1],使用Python,很轻松就能获取到该列表,代码如下(该代码用于拼接生成vue代码,这是后文踩坑后的一种权宜之计):
import requests
import json
url = 'https://open.ys7.com/api/lapp/device/list'
vue_str = r''' <WelcomeItem>
<template #icon>
<ToolingIcon />
</template>
<template #heading>{0}</template>
<a href="/player/?id={1}&template=pcRec" target="_blank">查看视频</a>
</WelcomeItem>'''
# 参数
params = {
'accessToken': 'your_access_token',
'pageStart': '0',
'pageSize': '40'
}
r = requests.post(url, params=params)
json_data = r.json()
for item in json_data['data']:
device_info = vue_str.replace('{0}', item['deviceName']).replace('{1}', item['deviceSerial'])
print(device_info)
一切非常顺利,于是,我打算在axios里调用该接口,想着也应该相当顺利……
于是我写下了如下代码,并期待着正确的结果。
axios
调用接口
<script setup lang="ts">
import {
onMounted } from 'vue';
import WelcomeItem from './WelcomeItem.vue'
import ToolingIcon from './icons/IconTooling.vue'
import axios from 'axios';
import {
ACCESS_TOKEN } from '../config/constants';
const devices = ref<any>([]);
const fetchDevices = async () => {
try {
const response = await axios.post('https://open.ys7.com/api/lapp/device/list',
{
accessToken: ACCESS_TOKEN, pageStart: 0, pageSize: 40});
if (response.status === 200) {
devices.value = response.data.data;
console.log(response.data)
} else {
console.error('Failed to fetch devices:', response.statusText);
}
} catch (error) {
console.error('Error fetching devices:', error);
}
};
onMounted(() => {
fetchDevices();
});
</script>
<template>
<WelcomeItem v-for="(device) in devices" :key="device.id">
<template #icon>
<ToolingIcon />
</template>
<template #heading>{
{
device.deviceName }}</template>
<a :href="'/player/?id=' + device.deviceSerial + '&template=pcRec'" target="_blank">回放</a>
<a :href="'/player/?id=' + device.deviceSerial + '&template=pcLive'" target="_blank">直播</a>
</WelcomeItem>
</template>
然而,我却等来了:
{
"msg": "accessToken过期或异常",
"code": "10002"
}
再看我传入的内容
也按照对象传入,并没有什么不妥……
显然,这不是我想要的,我的 AccessToken
也明明没有过期(Python程序运行良好)。我苦苦寻觅,百思不得其解,并一度怀疑我拿到的应用类型智能用于服务器后台程序调用(参考百度,区分服务器调用或浏览器调用的不同 AK
)。
莫非我的传参方式错了?我陷入了回忆之中……
axios POST
传参方式
1. 传递普通对象
这就是我使用的方式,将数据封装在一个普通 JavaScript 对象中,并将其作为请求体发送给服务器。这种传参方式适用于大多数情况,特别是当我们需要向服务器提交表单数据或其他简单的结构化数据时。例如:
// 假设要发送的数据是一个包含用户信息的对象
const userData = {
username: 'john_doe',
email: '[email protected]',
age: 25
};
axios.post('/api/users', userData)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
2. 传递FormData对象
上传文件或者发送包含文件和表单数据的请求时,可以使用 FormData
对象。FormData
对象可以方便地构建一个键值对集合,并在发送请求时将其作为请求体。
// 使用 FormData 对象来上传文件或表单数据
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('title', 'My File');
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data' // 设置请求头,确保服务器正确解析 FormData
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
3. URL参数传递
查询字符串传参,在我看来最淳朴,最直接的方式,但这种URL传参我一直认为有点原始,当然也可以使用URLSearchParams
对象用于简化传递 URL 参数的过程。它允许我们使用一种更简洁的方式来指定 URL 参数,而无需手动构造 URL 查询字符串。
// 使用 URLSearchParams 对象来简化传递 URL 参数
const params = new URLSearchParams();
params.append('search', 'keyword');
axios.post('/api/search', params)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
当然,除了这些传参方式,也可以设置请求配置,具体也可看文档,我也尝试纠结于方式1并不断改配置时,我再看了萤石云官网文档一眼,仅此一眼,我用上了它正确的打开方式……
壮哉我大&
哥,&
在了,?
就不远了……这是不是意味着方式三才是接口调用的正确打开方法?talk is cheap,show you the code:
const fetchDevices = async () => {
try {
const response = await axios.post(`https://open.ys7.com/api/lapp/device/list?accessToken=${
ACCESS_TOKEN}&pageStart=0&pageSize=40`);
if (response.status === 200) {
devices.value = response.data.data;
console.log(response.data)
} else {
console.error('Failed to fetch devices:', response.statusText);
}
} catch (error) {
console.error('Error fetching devices:', error);
}
};
果然,成功了:
总结
接口的调用,真的要认真看官方文档啊,不过这个也太隐晦、太坑了吧,如果有示例代码就最好了,也可能是我最开始用Python调用,形成了习惯了。
另:配上个后台,我认为在后台和这些接口对接,然后前端页面访问自己搭建的后台,才是更好的方式。