Google Apps Script自定义函数GET_REDIRECT_LOCATION无法处理Meta Refresh重定向及URL对象报错的修复方案咨询
Google Apps Script自定义函数GET_REDIRECT_LOCATION无法处理Meta Refresh重定向及URL对象报错的修复方案咨询
我看到你在使用Google Apps Script自定义函数GET_REDIRECT_LOCATION时遇到了两个核心问题:一是处理Meta Refresh重定向时抛出ReferenceError: URL is not defined错误,二是部分URL无法正确识别重定向地址。让我一步步帮你排查并修复这些问题:
问题1:URL对象未定义的原因及修复
Google Apps Script默认的旧版Rhino JavaScript引擎不支持ES6引入的URL对象,这就是你触发ReferenceError的直接原因。我们可以通过两种方式解决:
方案A:手动解析Base URL(兼容所有运行环境)
不用URL对象,通过字符串截取的方式手动提取URL的协议和主机部分,替换你代码中所有使用new URL(url)的逻辑:
// 替换原来的URL对象解析逻辑,手动提取协议和主机 function getBaseProtocolAndHost(url) { let protocol = 'https://'; let host = ''; // 提取协议 const protocolSplit = url.split('://'); if (protocolSplit.length === 2) { protocol = protocolSplit[0] + '://'; url = protocolSplit[1]; } // 提取主机(从开头到第一个/的部分) const hostSplit = url.split('/'); if (hostSplit.length > 0) { host = hostSplit[0]; } return { protocol, host }; }
然后在处理相对URL时调用这个函数:
// 处理相对URL - 转为绝对路径 if (redirectUrl.startsWith('/')) { const { protocol, host } = getBaseProtocolAndHost(url); redirectUrl = protocol + host + redirectUrl; }
方案B:切换到V8运行时(更简洁)
如果你的脚本项目允许,直接切换到V8引擎即可原生支持URL对象:
- 打开Apps Script编辑器
- 点击右上角的「设置」图标
- 勾选「启用新的Apps Script运行时(V8)」
- 保存并重新运行脚本
问题2:Meta Refresh重定向正则匹配优化
你当前的正则表达式/content=["']?\d+;\s*url=([^"'\s>]+)["']?/i可能会遗漏部分Meta Refresh格式,比如未精准匹配http-equiv="refresh"的标签。建议修改为更精准的正则:
// 优化后的Meta Refresh匹配正则,优先匹配带有http-equiv="refresh"的标签 const metaRefresh = content.match(/<meta\s+http-equiv=["']?refresh["']?\s+content=["']?\d+;\s*url=([^"'>]+)["']?/i);
这个正则会先定位到专门的Refresh Meta标签,避免误匹配其他包含content属性的标签。
修复后的完整代码
整合以上修复点,最终的函数代码如下:
/** * Returns the redirect location of a url. * * @param {string} input The source URL being redirected. * @return The destination location/URL. * @customfunction */ function GET_REDIRECT_LOCATION(input) { // Basic validation if (!input) return "INVALID_URL"; let url = input.toString().trim(); if (!url || !url.includes(".")) return "INVALID_URL"; // Add https if no protocol if (!url.startsWith("http")) { url = "https://" + url; } // 辅助函数:手动解析URL的协议和主机 function getBaseProtocolAndHost(targetUrl) { let protocol = "https://"; let host = ""; const protocolSplit = targetUrl.split("://"); if (protocolSplit.length === 2) { protocol = protocolSplit[0] + "://"; targetUrl = protocolSplit[1]; } const hostSplit = targetUrl.split("/"); if (hostSplit.length > 0) { host = hostSplit[0]; } return { protocol, host }; } try { // First try with followRedirects: false to catch HTTP redirects let response = UrlFetchApp.fetch(url, { muteHttpExceptions: true, followRedirects: false }); let status = response.getResponseCode(); // Check for HTTP redirect (3xx status codes) if (status >= 300 && status < 400) { const headers = response.getAllHeaders(); const location = headers.Location || headers.location; if (location) { return location; } } // Get the HTML content to check for meta redirects const content = response.getContentText(); // 优化后的Meta Refresh匹配逻辑 const metaRefresh = content.match(/<meta\s+http-equiv=["']?refresh["']?\s+content=["']?\d+;\s*url=([^"'>]+)["']?/i); if (metaRefresh && metaRefresh[1]) { let redirectUrl = metaRefresh[1]; // Handle relative URLs - make them absolute if (redirectUrl.startsWith('/')) { const { protocol, host } = getBaseProtocolAndHost(url); redirectUrl = protocol + host + redirectUrl; } return redirectUrl; } // Check for canonical URL as backup const canonical = content.match(/<link[^>]*rel=["']canonical["'][^>]*href=["']([^"']+)["']/i); if (canonical && canonical[1]) { let canonicalUrl = canonical[1]; // Handle relative URLs if (canonicalUrl.startsWith('/')) { const { protocol, host } = getBaseProtocolAndHost(url); canonicalUrl = protocol + host + canonicalUrl; } if (canonicalUrl !== url) { return canonicalUrl; } } return "NO_REDIRECTS_FOUND"; } catch (error) { return "ERROR: " + error.toString(); } }
额外优化建议
- 处理带参数的相对URL:如果遇到类似
../path的相对路径,当前逻辑无法处理,你可以进一步补充相对路径解析逻辑 - 增加超时设置:在
UrlFetchApp.fetch的参数中添加timeout: 10000(10秒超时),避免因目标服务器响应慢导致函数卡死 - 验证重定向URL有效性:返回重定向地址前,可以额外验证地址格式,避免返回无效路径
用你提供的VSCode博客URL测试修复后的函数,应该能正确返回完整的目标重定向地址。
内容来源于stack exchange
相关产品推荐
相关产品推荐

