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栏中查看