在上一篇文章"使用cloudflare worker通过302重定向创建必应壁纸api地址"中的代码依赖于github,经过改善,下面的代码不再需要用到action
- 首先创建一个cloudflare worker项目,导入最下面的代码
- 创建KV Namespaces命名空间,名称随意,添加一个名为’BingJSON‘的键,键值任意
- 绑定创建的KV命名空间到刚创建的worker项目,并命名为’CRONBIN‘
- 自定义域名,cloudflare给的worker.dev域名国内是访问不了的
/UHD.jpg
/FHD.jpg
/HD.jpg
export default {
async fetch(request, env, ctx) {
let data = {};
let url = new URL(request.url);
// '['/UHD.jpg', '/FHD.jpg', '/HD.jpg']'
let deviceType = getDeviceType(request.headers.get('User-Agent'));
let BingURL = await getBingWallpaperURL(url, deviceType, env);
if (isValidUrl(BingURL)) return Response.redirect(BingURL, 302);//重定向到必应壁纸URL
else { data.BingURL = BingURL ?? 'null'; }
return new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*' // 允许任意域名访问
},
status: 200, // 设置状态码为 200 表示成功响应
statusText: 'OK' // 可选,设置状态文本
});
}
}
// 获取设备类型
function getDeviceType(userAgent) {
let mobileRegex = /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/;
return mobileRegex.test(userAgent) ? 'mobile' : 'desktop';
}
// 验证URL是否合法
function isValidUrl(url) {
let urlPattern = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;
return urlPattern.test(url);
}
// 验证日期是否合法
function checkDateFormat(enddate) {
if (typeof enddate !== 'string' || enddate.length !== 8) {
throw `${enddate}不是字符串,或者字符串长度不是8位`;
};
// const regex = /^(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/; // 使用正则表达式匹配年月日格式,如20231029
// if (!regex.test(enddate)) { throw `${enddate}不是年月日格式的日期` };
let year = parseInt(enddate.substring(0, 4), 10);
let month = parseInt(enddate.substring(4, 6), 10);
let day = parseInt(enddate.substring(6, 8), 10);
let date = new Date(year, month - 1, day);
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { throw `${enddate}不是年月日格式的日期` };
return true
}
// 获取当前日期,北京时间
function getDate() {
let currentDate = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
const dateParts = currentDate.split(/\D/);
const year = dateParts[0];
const month = dateParts[1].padStart(2, '0');
const day = dateParts[2].padStart(2, '0');
let nowdate = `${year}${month}${day}`
if (checkDateFormat(nowdate)) { return nowdate };
throw '获取当前日期的年月日格式失败';
}
async function getBingJSON() {
let apiUrl = 'https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN';
return new Promise((resolve, reject) => {
fetch(apiUrl, {
headers: {
'Accept': 'application/json', // 设置请求标头为JSON
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35', // 设置自定义的 User-Agent
'Referer': 'same-origin' // 设置 Referer 为 same-origin
}
}).then(response => {
if (!response.ok) throw `网页${apiUrl}爬取失败`;
let contentType = response.headers.get('Content-Type');
if (!contentType || !contentType.includes('application/json')) { throw '返回的数据不是JSON格式' };// 检查响应的内容类型
response.json().then(jsonData => {
console.log(jsonData); resolve(jsonData);
}).catch(err => { console.error(err); reject(err); });
}).catch(err => { console.error(err); reject(err); });
});
}
// 获取必应壁纸URL
async function getBingWallpaperURL(url, deviceType, env) {
if (url.pathname === '/UHD.jpg' || url.pathname === '/FHD.jpg' || url.pathname === '/HD.jpg') {
let data; let NotJSON;
try {
data = await env.CRONBIN.get('BingJSON').then(BingJSON => {
data = JSON.parse(BingJSON); return data
}).catch(err => { console.error(err); NotJSON = true; });
if (NotJSON) {
let response = await getBingJSON();
let kv_response = await env.CRONBIN.put('BingJSON', JSON.stringify(response));
data = response; data.update = 'BingJSON is not JSON string, Update BingJSON success';
} else {
let enddate = data.images[0].enddate ?? 'BingJSON have no enddate property';
checkDateFormat(enddate); let nowdate = getDate();
if (nowdate !== enddate) { //update url
let response = await getBingJSON();
let kv_response = await env.CRONBIN.put('BingJSON', JSON.stringify(response));
data = response; data.update = 'Update BingJSON success';
}
};
let imageUrl = 'https://www.bing.com' + data.images[0].urlbase;
let imageUHDUrl = imageUrl + '_UHD.jpg';
let imageHDUrlMobile = imageUrl + '_768x1366.jpg';
let imageHDUrlDesktop = imageUrl + '_1366x768.jpg';// 1280x720
let imageFHDUrlMobile = imageUrl + '_1080x1920.jpg';
let imageFHDUrlDesktop = imageUrl + '_1920x1080.jpg';
switch (url.pathname) {
case '/UHD.jpg': var BingURL = deviceType === 'mobile' ? imageFHDUrlMobile : imageUHDUrl; // 根据设备类型设置分辨率
break;
case '/FHD.jpg': BingURL = deviceType === 'mobile' ? imageFHDUrlMobile : imageFHDUrlDesktop; // 根据设备类型设置分辨率
break;
case '/HD.jpg': BingURL = deviceType === 'mobile' ? imageHDUrlMobile : imageHDUrlDesktop; // 根据设备类型设置分辨率
break;
case '/': BingURL = data;
}
return BingURL
} catch (error) {
console.error(error);
data.error = error;
return data
}
} else return `Not Found url.pathname:${url.pathname.substring(1)}`
}