
在 react 应用中,当使用自定义 `usescript` hook 注入外部 javascript 文件时,若采用相对路径,在标准路由下可能正常工作,但在动态路由下则可能因路径解析错误导致脚本加载失败,并抛出“unexpected token '
在现代前端应用,尤其是基于 React 的单页应用(SPA)中,动态加载外部 JavaScript 脚本是一种常见的需求,例如集成第三方分析工具、广告SDK或特定功能的库。通常,我们会封装一个自定义 Hook(如 useScript)来管理脚本的生命周期,包括创建、加载、错误处理和清理。
然而,在处理脚本路径时,一个常见的陷阱是使用相对路径。当 React Router 等库引入动态路由时,相对路径的解析行为会发生变化,从而导致脚本加载失败。
以下是一个典型的 useScript Hook 实现,它负责将指定 URL 的脚本注入到 document.head 中:
import { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
const useScript = (url) => {
const [status, setStatus] = useState(url ? 'loading' : 'idle')
const location = useLocation() // 引入 useLocation 以在路由变化时重新评估
useEffect(() => {
if (!url) {
setStatus('idle')
return
}
let script = document.querySelector(`script[src="${url}"]`)
if (!script) {
script = document.createElement('script')
script.src = url
script.type = 'text/javascript'
script.async = true
document.head.appendChild(script)
const setAttributeFromEvent = (event) => {
script.setAttribute(
'data-status',
event.type === 'load' ? 'ready' : 'error'
)
}
script.addEventListener('load', setAttributeFromEvent)
script.addEventListener('error', setAttributeFromEvent)
} else {
// 如果脚本已存在,则从其 data-status 属性获取状态
setStatus(script.getAttribute('data-status'))
}
const setStateFromEvent = (event) => {
setStatus(event.type === 'load' ? 'ready' : 'error')
}
script.addEventListener('load', setStateFromEvent)
script.addEventListener('error', setStateFromEvent)
return () => {
if (script) {
script.removeEventListener('load', setStateFromEvent)
script.removeEventListener('error', setStateFromEvent)
}
}
}, [url, location]) // 依赖项中包含 url 和 location
return status
}
export default useScript这个 Hook 在标准路由(如 /offer)下可能工作正常,但在动态路由(如 /hearing-agency/brand/:brandname)下,当 useScript('./tagging.js') 被调用时,就会出现问题。
当你在 React 组件中使用 useScript('./tagging.js') 这样的相对路径时,浏览器会根据当前页面的 URL 来解析这个相对路径。
问题就在于,在动态路由的场景下,浏览器会尝试从 http://localhost:3000/hearing-agency/brand/ 路径下去查找 tagging.js。如果你的 tagging.js 文件实际上位于 public 文件夹的根目录,那么这个解析后的 URL 将是错误的。服务器会返回一个针对 http://localhost:3000/hearing-agency/brand/tagging.js 的 404 错误页面,或者在开发服务器中,它可能会返回应用的 index.html 文件。
当浏览器尝试将一个 HTML 文件(或 404 错误页面)作为 JavaScript 脚本来解析时,它会遇到 < 符号(HTML 文件的起始标签),这在 JavaScript 语法中是非法的,因此会抛出 SyntaxError: Unexpected token '<' 错误。
解决此问题的最直接和最可靠的方法是使用绝对路径来引用你的脚本文件。绝对路径会从 Web 根目录开始解析,而不受当前 URL 路径的影响。
将 useScript('./tagging.js') 修改为 useScript('/tagging.js') 即可。
// 在组件中调用 useScript
import useScript from './hooks/useScript'; // 假设 useScript 在此路径
function MyComponent() {
// 使用绝对路径引用脚本
const status = useScript('/tagging.js');
console.log('Script status:', status);
// ... 组件的其他逻辑
}通过将路径更改为 /tagging.js:
在 React 应用中,当使用自定义 Hook 动态注入脚本并遇到“Unexpected token '<'”错误时,尤其是在动态路由下,最常见的原因是脚本路径解析不正确。通过将脚本的相对路径(如 ./tagging.js)修改为绝对路径(如 /tagging.js),可以确保浏览器始终从应用的根目录正确加载静态资源,从而避免此类错误。理解相对路径和绝对路径在 Web 环境中的解析机制,是构建健壮的单页应用的关键。
以上就是React 动态路由下脚本注入失败的解决方案的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号