MediaWiki后端登录API调用异常,无法获取logintoken求助
MediaWiki登录API调用失败:无法获取logintoken的解决方法
我将MediaWiki作为后端服务部署在localhost/name,使用React结合Axios编写login.js调用登录API时出现异常:第一个GET请求的URL拼接错误,返回响应不符合文档预期,无法正确获取logintoken。相关信息如下:
登录代码(login.js)
import React, {useState} from 'react'; import axios from 'axios'; function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); async function login() { console.log(username, password); let url = 'http://localhost/wikimedia/api.php'; let params = { action: "query", meta: "tokens", format: "json", type: "login" }; // fetch login const response = await axios.get(url + '?' + params + '&origin=*'); console.log(response); let loginToken = response.data.query.tokens.logintoken let cookie = response.headers['set-cookie'].join(';'); let body = { action: 'login', lgname: username, lgpassword: password, lgtoken: loginToken, format: 'json' } let bodyData = new URLSearchParams(body).toString(); axios.post(url, bodyData, { headers: { Cookie: cookie, } }).then(response => { let cookie = response.headers['set-cookie'].join(';') console.log(response.data); }) } return ( <div> <h1>Sign In</h1> <input type="text" onChange={(e) => setUsername(e.target.value)} placeholder="username" /> <br/> <input type="password" onChange={(e) => setPassword(e.target.value)} placeholder="password" /> <br/> <button onClick={login} type="submit">Login</button> </div> ) }; export default Login;
实际错误响应
{ "data": "a-bunch-of-irrelevant-stuff", "status": 200, "statusText": "OK", "headers": { "cache-control": "private, must-revalidate, max-age=0", "content-language": "en", "content-type": "text/html; charset=utf-8", "expires": "Thu, 01 Jan 1970 00:00:00 GMT", "mediawiki-login-suppressed": "true" }, "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, "headers": { "Accept": "application/json, text/plain, */*" }, "method": "get", "url": "http://localhost/wikimedia/api.php?[object Object]&origin=*" }, "request": {} }
预期响应
{ "batchcomplete": "", "query": { "tokens": { "logintoken": "9ed1499d99c0c34c73faa07157b3b6075b427365+\\" } } }
错误原因
核心问题是手动拼接URL参数时,直接将params对象与字符串拼接,导致对象被转成[object Object],生成了无效的URL。MediaWiki无法识别这种参数格式,因此返回HTML页面而非预期的JSON响应,自然无法提取logintoken。
修复方案
利用Axiosget方法自带的params配置项,它会自动将对象序列化为合法的URL参数,同时把origin=*加入参数列表解决跨域问题:
修复后的完整代码
import React, {useState} from 'react'; import axios from 'axios'; function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); async function login() { console.log(username, password); const url = 'http://localhost/wikimedia/api.php'; // 合并origin参数到params中,Axios会自动处理URL拼接 const params = { action: "query", meta: "tokens", format: "json", type: "login", origin: "*" }; // 使用Axios的params配置,自动生成正确的URL参数 const response = await axios.get(url, { params }); console.log(response); try { const loginToken = response.data.query.tokens.logintoken; const cookie = response.headers['set-cookie'].join(';'); const body = { action: 'login', lgname: username, lgpassword: password, lgtoken: loginToken, format: 'json' }; const bodyData = new URLSearchParams(body).toString(); const loginResponse = await axios.post(url, bodyData, { headers: { Cookie: cookie, } }); const newCookie = loginResponse.headers['set-cookie'].join(';'); console.log(loginResponse.data); } catch (error) { // 捕获异常,处理登录失败情况 console.error('登录出错:', error); } } return ( <div> <h1>Sign In</h1> <input type="text" onChange={(e) => setUsername(e.target.value)} placeholder="username" /> <br/> <input type="password" onChange={(e) => setPassword(e.target.value)} placeholder="password" /> <br/> <button onClick={login} type="submit">Login</button> </div> ) }; export default Login;
补充说明
- 修复后,GET请求会自动生成
http://localhost/wikimedia/api.php?action=query&meta=tokens&format=json&type=login&origin=*这样的合法URL,MediaWiki会返回预期的JSON响应,就能正常提取logintoken。 - 新增了
try/catch块捕获异常,避免因网络错误、响应格式异常导致页面崩溃。 - POST请求部分使用
URLSearchParams处理请求体的方式是正确的,符合MediaWiki API的要求。
内容的提问来源于stack exchange,提问作者pipocaDourada
相关产品推荐
相关产品推荐

