You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

补充说明

  1. 修复后,GET请求会自动生成http://localhost/wikimedia/api.php?action=query&meta=tokens&format=json&type=login&origin=*这样的合法URL,MediaWiki会返回预期的JSON响应,就能正常提取logintoken。
  2. 新增了try/catch块捕获异常,避免因网络错误、响应格式异常导致页面崩溃。
  3. POST请求部分使用URLSearchParams处理请求体的方式是正确的,符合MediaWiki API的要求。

内容的提问来源于stack exchange,提问作者pipocaDourada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:55:23