【React】通过 fetch 发起请求,设置 proxy 处理跨域

发布于:2025-04-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

fetch 基本使用

在node使用原生ajax发请求:XMLHttpRequest()
            1.获取xhr对象  2.注册回调函数  3.设置参数,请求头  4.发起连接
            原生ajax没有带异步处理 promise;原生ajax封装一下,以便重复调用

jQuery:$ajax()

Vue:axios

React:fetch 已经封装好的ajax,并且带promise处理

src\utils\http.js(请求的封装)

/*
    http({
        url:"",
        method:"",
        params:{}  |  data:{}    --------get请求params,post请求data
    }).then(res=>{
        //在这里直接拿到数据,不想要两次.then才拿到
    })

    使用token的内容也封装进去
*/

const BASE_URL = '/api'  //基础请求路径  http://172.16.235.16:8888

/*封装分析:get请求数据拼接到url
	    let xxx={
	        id:1,
	        username:"admin",
	        password:123
	    }
	
	    fetch("http://localhost:8888/login/getuser?id=1&username=admin&password=123")
	
	    fetch("http://localhost:8888/login/getuser?"+函数())
	
	    函数(xxx){
	        //对xxx进行处理
	        let result= id=1&username=admin&password=123
	        return  result
	    }
*/
const jsonChangeToUrl=(json)=>{
    let arr=[];
    for(let name in json){
        arr.push(name+"="+json[name]);  //[id=1,name=admin,pwd=123]
    }
    return arr.join("&");  //"id=1&name=admin&pwd=123"
}

const http=({url,method='get',params={},data={}})=>{

    if(!url)return; //如果没有传递请求路径,就结束请求

    const token=sessionStorage.getItem("token") || ""; //发起请求之前先获取token

    let options={
        method,
        headers:{
            token
        },
        // body:JSON.stringify(data)
    }
    if(method.toLowerCase()==='post'){
        options.body=JSON.stringify(data)
    }

    return fetch(BASE_URL+url+"?"+jsonChangeToUrl(params),options)
        .then(response => {
            if(response.status === 401){ //token失效
                window.location.href="/login";  //浏览器url地址栏
            }else {
                return response.json();
            }

        })
}


export default http;

src\pages\login\index.js (使用fetch发起请求)

import { Button,Form, Input,Radio,message } from 'antd';
import './index.scss'
import {useNavigate} from "react-router-dom";
import http from "../../utils/http"; //二次封装后的fetch


const Login = () => {

    const navigate = useNavigate();

    //点击登录时触发
    const onFinish = values => { //表单提交触发函数,value:表单输入框的值
        // console.log('Success:', values);  //{id:1,username:admin,type:管理员}

        //未封装过的fetch发的请求
        /*fetch("http://localhost:8888/login/getuser?username=201&password=201&type=管理员")
            .then(resp => {
                console.log(resp)
                return resp.json()  //resp.json()是将返回的数据转为对象给我用;resp.text()返回的只是单纯的文本时可用
            })
            .then(data => {
                console.log(data)
            })
            .catch((err)=>{
                console.log("错误信息:"+err)
        })*/
        //自己封装的fetch
        http({
            url:"/login/getuser",
            params:values
        }).then(res => {
            console.log(res)
            sessionStorage.setItem("token",res.token)
            sessionStorage.setItem("user",JSON.stringify(res.data[0]))
            sessionStorage.setItem("power",JSON.stringify(res.power))
            if(res.code === 200){
                message.success("登录成功") //提示气泡
                navigate("/home");
            }
        })

    };
    return (
        <div className={"loginBox"}>
            <Form
                name="basic"
                labelCol={{ span: 5 }}
                wrapperCol={{ span: 16 }}
                initialValues={{  //初始值
                    roleLgoin:"学生"  //绑在checkbox上的
                }}
                onFinish={onFinish}
                autoComplete="off"
            >
                <Form.Item
                    label="用户名"
                    name="username"
                    rules={[{ required: true, message: '请输入您的用户名!' }]}
                >
                    <Input />
                </Form.Item>

                <Form.Item
                    label="密码"
                    name="password"
                    rules={[{ required: true, message: '请输入您的密码名!' }]}
                >
                    <Input.Password />
                </Form.Item>

                <Form.Item name="roleLgoin" label={null}>
                    <Radio.Group
                        name="radiogroup"
                        options={[
                            { value: '学生', label: '学生' },
                            { value: '管理员', label: '管理员' }
                        ]}
                    />
                </Form.Item>

                <Form.Item label={null}>
                    <Button type="primary" htmlType="submit">
                        Submit
                    </Button>
                </Form.Item>
            </Form>
        </div>
    )

}

export default Login;

跨域处理

1.react配置文件暴露弹出来:
                      git add .
                      git commit -m 'msg'
                      npm run eject

2.找到配置文件:webpackDevServer.config.js  //在103行的proxy属性,代理只在开发阶段有用,项目上线要删掉

                proxy:{
                    '/api':{
                        target: 'http://localhost:8888',
                        changeOrigin: true,
                        pathRewrite: {
                            '^/api': ' '
                        }
                    }
                }

不建议直接暴露文件的不可逆操作,建议使用 craco (create-react-app config)在 React 脚手架的基础上进行 Webpack 配置。具体内容在Webpack\Vite栏中查看


网站公告

今日签到

点亮在社区的每一天
去签到