如何通过注入React JS代码实现无界面自动登录并跳转目标页
React页面后台自动完成第三方登录(不显示登录页)
我是前端和React新手,试了好几种方法都没成功。需求是:打开我的React页面后,不用从当前页重定向,自动访问https://192.168.6.146/login,自动填入用户信息完成登录,而且不能显示这个登录页面。经理说可以通过在React页面注入JS实现,但现在我的代码打开是空白页,附上我的尝试代码,求帮忙。
import * as React from 'react'; import { Col, Row, Typography } from 'antd'; // var url = 'https://192.168.6.146/login'; // export const openInNewTab = (url: string): void => { // const newWindow = window.open(url, '_blank', 'noopener,noreferrer') // if (newWindow) newWindow.opener = null // } // export const onClickUrl = (url: string): (() => void) => () => openInNewTab(url) // var theWindow = window.open('https://192.168.6.146/login'), // theScript = document.createElement('script'); // function injectThis() { // // The code you want to inject goes here // alert(document.body.innerHTML); // } // // Self executing function // theScript.innerHTML = '(' + injectThis.toString() + '());'; // theWindow.onload = function () { // // Append the script to the new window's body. // // Only seems to work with `this` // this.document.body.appendChild(theScript); // }; // function RedirectExample() { // React.useEffect(() => { // const timeout = setTimeout(() => { // window.location.replace('https://192.168.6.146/login'); // }, 3000); // return () => clearTimeout(timeout); // }, []); // return <>Will redirect in 3 seconds...</>; // } // function RedirectReactRouterExample() { // return ( // <Routes> // <Route path="/" element={<Index />} /> // <Route path="about" element={<About />} /> // </Routes> // ); // } // function About() { // return <div>About</div>; // } // function Index() { // const navigate = useNavigate(); // useEffect(() => { // setTimeout(() => { // navigate('/about', { replace: true }); // }, 3000); // }, []); // return <div>Redirecting...</div>; // } // export class HoopWorks extends React.Component<any> { // render() { // return ( // <Routes> // <Route path="https://192.168.6.146/login" element={<Index />} /> // <Route path="about" element={<About />} /> // </Routes> // ); // } // } // export default HoopWorks; // var session_url = 'https://192.168.6.146/hopsworks-api/api/auth/login'; // var querystring = require('querystring'); // axios.post(session_url, querystring.stringify({ // username: 'admin', //gave the values directly for testing // password: 'admin' // }), { // headers: { // 'content-type' : 'application/x-www-form-urlencoded;charset=utf-8', // "Access-Control-Allow-Origin" : "*", // 'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS', // } // }).then(function(response) { // console.log('Authenticated'); // }).catch(function(error) { // console.log('Error on Authentication'); // }); export class HoopWorks extends React.Component<any> { render() { return ( <Row> <Col span={8} offset={10} style={{marginTop:50}}> <Typography style={{fontSize:'50px'}}>{'HoopWorks-iFrame Page'}</Typography> </Col> </Row> ); } } export default HoopWorks;
方案一:直接调用登录API(优先推荐)
如果目标系统提供无界面的登录接口(比如你注释里的/hopsworks-api/api/auth/login),直接调用接口是最简洁的方案,无需加载登录页面。核心要解决跨域问题:
- 若React项目与目标系统同域,或目标接口配置了CORS允许你的域名,可直接用axios/fetch调用
- 跨域无法解决时,需在React项目后端做反向代理转发登录请求
修改后的代码示例:
import * as React from 'react'; import { Col, Row, Typography } from 'antd'; import axios from 'axios'; export class HoopWorks extends React.Component<any> { componentDidMount() { // 组件挂载后自动执行登录 this.autoLogin(); } async autoLogin() { try { const loginUrl = 'https://192.168.6.146/hopsworks-api/api/auth/login'; const response = await axios.post(loginUrl, new URLSearchParams({ username: 'admin', password: 'admin' }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }, // 需要保存会话cookie时开启 withCredentials: true }); console.log('登录成功:', response.data); // 登录成功后可执行后续逻辑,比如获取用户信息 } catch (error) { console.error('登录失败:', error); // 处理失败场景,比如提示用户 } } render() { return ( <Row> <Col span={8} offset={10} style={{ marginTop: 50 }}> <Typography style={{ fontSize: '50px' }}>HoopWorks-iFrame Page</Typography> </Col> </Row> ); } } export default HoopWorks;
关键注意点
- 确认登录接口参数格式:部分接口要求JSON格式,需调整为
axios.post(loginUrl, {username: 'admin', password: 'admin'}) - 开发环境跨域解决:在
package.json添加代理配置
调用时用相对路径:"proxy": "https://192.168.6.146"/hopsworks-api/api/auth/login
方案二:隐藏iframe模拟浏览器登录
如果必须通过加载登录页完成登录(比如有前端验证、需渲染表单),可使用隐藏iframe加载登录页,注入脚本自动填参提交。但要注意跨域限制:仅当React页面与目标登录页同域,或目标页面允许跨域操作(如设置document.domain),才能操作iframe内DOM。
修改后的代码示例:
import * as React from 'react'; import { Col, Row, Typography } from 'antd'; export class HoopWorks extends React.Component<any> { private loginIframe: HTMLIFrameElement | null = null; componentDidMount() { this.createHiddenLoginIframe(); } createHiddenLoginIframe() { // 创建隐藏iframe const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = 'https://192.168.6.146/login'; iframe.onload = () => this.injectLoginScript(iframe); document.body.appendChild(iframe); this.loginIframe = iframe; } injectLoginScript(iframe: HTMLIFrameElement) { try { const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document; if (!iframeDoc) return; // 注入自动登录脚本 const script = document.createElement('script'); script.textContent = ` setTimeout(() => { // 需根据目标登录页实际DOM结构修改选择器 const usernameInput = document.getElementById('username'); const passwordInput = document.getElementById('password'); const loginBtn = document.getElementById('login-btn'); if (usernameInput && passwordInput && loginBtn) { usernameInput.value = 'admin'; passwordInput.value = 'admin'; loginBtn.click(); console.log('自动登录脚本执行完成'); } else { console.error('未找到登录表单元素'); } }, 1000); // 延迟确保表单渲染完成 `; iframeDoc.body.appendChild(script); } catch (error) { console.error('注入脚本失败:', error); // 跨域时会触发此错误,无法操作iframe内DOM } } componentWillUnmount() { // 组件卸载时清理iframe if (this.loginIframe) { document.body.removeChild(this.loginIframe); } } render() { return ( <Row> <Col span={8} offset={10} style={{ marginTop: 50 }}> <Typography style={{ fontSize: '50px' }}>HoopWorks-iFrame Page</Typography> </Col> </Row> ); } } export default HoopWorks;
关键注意点
- 需根据目标登录页的实际DOM结构调整脚本中的元素选择器(如输入框的id、class)
- 若目标站点设置
X-Frame-Options禁止嵌入iframe,此方案失效 - 跨域场景下,浏览器会阻止访问iframe的document对象,需改用其他登录方式
关于之前的空白页问题
你之前的尝试代码中,部分逻辑(如修改window.location、新开窗口)会导致页面跳转或窗口切换,若注释代码未完全清理,可能残留执行逻辑导致空白。确保只保留需要的代码,移除所有注释掉的尝试代码即可恢复正常渲染。
内容的提问来源于stack exchange,提问作者emrebalci
相关产品推荐
相关产品推荐

