import React, { useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { useTheme } from '../theme.jsx'; import { getToken } from '../api/client.js'; /** * 面板嵌入页(迁移自 embed.html): * 入口参数 ?url=&title=&proxy=1 —— iframe 展示目标站点; * proxy=1 或 HTTPS 页内嵌 HTTP 目标时走 /api/proxy/fetch?url=(代理剥 X-Frame-Options/CSP)。 * 工具栏:关闭(有来源则 history.back)、标题、原站(新标签)、主题切换。 */ export default function Embed() { const [searchParams] = useSearchParams(); const url = searchParams.get('url'); const title = searchParams.get('title') || url || '嵌入'; const useProxy = searchParams.get('proxy') === '1'; const { theme, toggleTheme } = useTheme(); const [showHint, setShowHint] = useState(false); const isHttpsPage = window.location.protocol === 'https:'; const isHttpTarget = url ? url.startsWith('http:') : false; const needsProxy = useProxy || (isHttpsPage && isHttpTarget); // proxy 模式:iframe 无法携带 Authorization header,改用 ?token= 认证(后端 queryTokenAuth 转写) const iframeSrc = url ? (needsProxy ? '/api/proxy/fetch?url=' + encodeURIComponent(url) + '&token=' + encodeURIComponent(getToken() || '') : url) : ''; // 非代理嵌入时 2s 后提示"无法嵌入?安装扩展"(照 v1) useEffect(() => { if (!url || needsProxy) return; const t = setTimeout(() => setShowHint(true), 2000); return () => clearTimeout(t); }, [url, needsProxy]); const handleClose = (e) => { // 有来源页时返回上一页,否则跳首页 if (document.referrer && document.referrer !== window.location.href) { e.preventDefault(); window.history.back(); } }; return (
缺少 url 参数,无法加载嵌入内容