react-router详解

react-router详解

React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。

路由的基本使用

安装react-router

cnpm install react-router-dom -D

使用react-router

环境准备:我使用antd的UI组件,所以需要下载依赖,并配置主题,==>Ant Design of React

需求

  1. 点击头部导航链接组件,在Context里面展示对应的组件内容
  2. 点击录入成绩,显示对应的组件,输入相关信息,提交信息到后台,并跳转到查询成绩中,显示信息
  3. 点击查询全部成绩,对应组件显示所有学生成绩信息

在这里插入图片描述

导航区

导航区的a标签改为Link标签
import {Link} from 'react-router-dom'
<Link to="/xxxxx">Demo</Link>

如:

import {Link} from 'react-router-dom'
(
            <>
                <h1>学生成绩管理系统</h1>
                <ul>
                    <li><Link to="/insetScore">录入成绩</Link></li>
                    <li><Link to={{pathname:"/findScore",state:{}}}>查询成绩</Link></li>
                 
                    <li><Link to="/updateScore">修改成绩</Link></li>
                    <li><Link to="/deteleScore">删除成绩</Link></li>
                    <li><Link to="/getAllScore">查看全部成绩</Link></li> 
                </ul>
            </>
        )

头部一般组件(<Link/>组件的使用)

components文件夹新建Header/index.jsxHeader/index.css文件

/*Header/index.jsx*/
import React, { Component } from 'react'
import {Link} from 'react-router-dom'

import  './index.css'

export default class Header extends Component {
    render() {
        return (
            <>
                <h1>学生成绩管理系统</h1>
                <ul>
                    <li><Link to="/insetScore">录入成绩</Link></li>
                    <li><Link to={{pathname:"/findScore",state:{}}}>查询成绩</Link></li>
                 
                    <li><Link to="/updateScore">修改成绩</Link></li>
                    <li><Link to="/deteleScore">删除成绩</Link></li>
                    <li><Link to="/getAllScore">查看全部成绩</Link></li> 
                </ul>
            </>
        )
    }
}
/*Header/index.css*/
h1{
    font: 30px bold 仿宋;				
    color: chocolate;
    text-align: center;
}
ul{ background-color: #dddddd;
   
}
li{	display: inline-block;
    margin-left: 5px;
    border:3px ;
    padding:5px;
    width: 17%;
    height: 30px;				
}
a{	display:block;
    text-decoration: none;
    color: chocolate;
    width: 100%;
    height: 30px;
    text-align: center;
}
li:hover {  background-color: white;
    border-top: 3px solid #ff7f00;			
}
a:hover{color: #ff7f00;	}

使用react-router-dom中的<Link/>标签包裹链接,浏览渲染为超链接a标签
在这里插入图片描述

展示区

展示区写Route标签进行路径的匹配。
<Route path='/xxxx' component={Demo}/>

如:

import {Route,Redirect,Switch} from 'react-router-dom'
       {/* 
          Switch可以提高路由匹配效率(单一匹配)。
      */}
        <Switch>  
            <Route path="/insetScore" component={AddStudent}/>
            <Route path="/findScore" component={Message}/>
            <Route path="/getAllScore" component={AllStudent}/>
            {/* 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由 */}
            <Redirect to="/insetScore"/>
        </Switch>
  • <Route path="/insetScore" component={AddStudent}/>:注册路由
  • <Switch> : 通常情况下,path和component是一一对应的关系。Switch可以提高路由匹配效率(单一匹配)。
  • <Redirect to="/insetScore"/>:一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
主体内容路由组件

src目录下新建pages目录用于存放路由组件

pages目录下创建主体内容Context/AllStudent.jsxContext/AddStudent.jsx,如果需要样式可以在这里创建,我这里没有所以不用创建

Context/AllStudent.jsx

import React, { Component } from 'react'
import axios from 'axios'
import { Table } from 'antd';
import uuid from 'react-uuid'
const { Column } = Table;

export default class AllStudent extends Component {

    state = {
        data: []
    }

    componentDidMount(){
        //没有请求参数
        axios.get('http://localhost:8080/api/getAllStudent')
        .then((response)=>{
            this.setState({data:response.data});
            console.info(response.data)
        })
        .catch((error)=>{
            console.log(error);
        });
    }


    render() {
        return (
            <>
            <h2 style={{textAlign:'center'}}>学生所有成绩信息显示</h2>
            <Table dataSource={this.state.data}>
               <Column title="姓名" dataIndex="name" key="name" />

               <Column title="数据库原理" dataIndex="databaseScore" key="databaseScore" />
               <Column title="大学英语" dataIndex="englishScore" key="englishScore" />
               <Column title="高等数学" dataIndex="mathScore" key="mathScore" />              
               <Column title="程序设计" dataIndex="programScore" key="programScore" />
               <Column title="总成绩"  key="sumScore" 
                  render={(text, record) => (
                   Object.keys(text).length !== 0?
                   (Number.parseInt(record.databaseScore)+
                   Number.parseInt(record.englishScore)+
                   Number.parseInt(record.mathScore)+
                   Number.parseInt(record.programScore))
                   :
                   " "
               )}
               />
               <Column title="平局成绩"  key="avgScore"  
                 render={(text, record) => (
                   Object.keys(text).length !== 0?
                   (Number.parseInt(record.databaseScore)+
                   Number.parseInt(record.englishScore)+
                   Number.parseInt(record.mathScore)+
                   Number.parseInt(record.programScore))/4
                   :
                   " "
               )}
               />  
           </Table>
           </>
        )
    }
}

Context/AddStudent.jsx

import React, { Component } from 'react'
import { Form, Input, Button } from 'antd';
import axios from 'axios'
import { message } from 'antd';

const layout = {
    labelCol: {
      span: 10,
    },
    wrapperCol: {
      span: 4,
    },
  };
  const tailLayout = {
    wrapperCol: {
      offset: 10,
      span: 16,
    },
  };


export default class Context extends Component {
  onFinish = (values) => {
      //有请求参数
      axios.post('http://localhost:8080/api/addStudent', {
        id: values.id,
        name: values.name,
        databaseScore: values.databaseScore,
        englishScore: values.englishScore,
        mathScore: values.mathScore,
        programScore: values.programScore,
      })
      .then(function (response) {
        if(response.data === "200"){
          console.info("=====================")
          message.success('添加学生消息成功!');
        }
        
      })
      .catch(function (error) {
        message.error('添加学生消息失败!');
      });

    this.props.history.push('/findScore',values);
    //console.log('Success:', values);



  };

  onFinishFailed = (errorInfo) => {
    console.log('Failed:', errorInfo);
  };
    render() {
        return (
           <>
           <h2 style={{textAlign:'center'}}>学生成绩信息输入</h2>
            <Form
                {...layout}
                name="basic"
                initialValues={{
                    remember: true,
                }}
                onFinish={this.onFinish}
                onFinishFailed={this.onFinishFailed}
                >
                <Form.Item
                    label="学号"
                    name="id"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的学号!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
              <Form.Item
                    label="姓名"
                    name="name"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的姓名!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
              <Form.Item
                    label="高等数学"
                    name="mathScore"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的高等数学成绩!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
              <Form.Item
                    label="大学英语"
                    name="englishScore"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的大学英语成绩!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
              <Form.Item
                    label="程序设计"
                    name="programScore"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的程序设计成绩!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
              <Form.Item
                    label="数据库原理"
                    name="databaseScore"
                    rules={[
                    {
                        required: true,
                        message: '请输入你的数据库原理成绩!',
                    },
                    ]}
                >
                <Input />
              </Form.Item>
                <Form.Item {...tailLayout}>
                    <Button type="primary" htmlType="submit">
                    Submit
                    </Button>
                </Form.Item>
             </Form>
             </>
        )
    }
}

pages/Message/index.jsx

注意: 如果组件下是index.jsx的形式,引入时可以导入到文件夹目录即可。默认为index.jsx
ex: import Message from './pages/Message'

import React, { Component } from 'react'
import { Table } from 'antd';
import uuid from 'react-uuid'
const { Column } = Table;

export default class Message extends Component {
    render() {
      const data = [];
      const data1 = this.props.location.state   || {};
      if(  Object.keys(data1).length !== 0 ){
          const item = {};
          item['key'] = uuid();
          item['name'] = data1['name']
          item['databaseScore'] = data1['databaseScore']
          item['englishScore'] =  data1['englishScore']
          item['mathScore'] =   data1['mathScore']
          item['programScore'] =  data1['programScore']
          data.push(item)      
      }
    //   console.info(data)
        return (
            <>
             <h2 style={{textAlign:'center'}}>学生成绩信息显示</h2>
             <Table dataSource={data}>
                <Column title="姓名" dataIndex="name" key="name" />

                <Column title="数据库原理" dataIndex="databaseScore" key="databaseScore" />
                <Column title="大学英语" dataIndex="englishScore" key="englishScore" />
                <Column title="高等数学" dataIndex="mathScore" key="mathScore" />              
                <Column title="程序设计" dataIndex="programScore" key="programScore" />
                <Column title="总成绩"  key="sumScore" 
                   render={(text, record) => (
                    Object.keys(text).length !== 0?
                    (Number.parseInt(record.databaseScore)+
                    Number.parseInt(record.englishScore)+
                    Number.parseInt(record.mathScore)+
                    Number.parseInt(record.programScore))
                    :
                    " "
                )}
                />
                <Column title="平局成绩"  key="avgScore"  
                  render={(text, record) => (
                    Object.keys(text).length !== 0?
                    (Number.parseInt(record.databaseScore)+
                    Number.parseInt(record.englishScore)+
                    Number.parseInt(record.mathScore)+
                    Number.parseInt(record.programScore))/4
                    :
                    " "
                )}
                />  
            </Table>
            </>
        )
    }
}

App.js


import React from 'react';
import './App.less';
import {Route,Redirect,Switch} from 'react-router-dom'
import Header from './components/Header'
// import Footer from './components/Footer'
import AddStudent  from './pages/Context/AddStudent'
import AllStudent  from './pages/Context/AllStudent'
import Message from './pages/Message'


const App = () => (
     <>
      <Header/>
      {/* 
          Switch可以提高路由匹配效率(单一匹配)。
      */}
        <Switch>  
            <Route path="/insetScore" component={AddStudent}/>
            <Route path="/findScore" component={Message}/>
            <Route path="/getAllScore" component={AllStudent}/>
            {/* 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由 */}
            <Redirect to="/insetScore"/>
        </Switch>
      {/* <Footer/> */}
    </>

);

export default App;

index.js

<App/>组件的最外侧包裹了一个<BrowserRouter>或<HashRouter>

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import {BrowserRouter} from 'react-router-dom'

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>

, document.getElementById('root'));

项目结构如下:
在这里插入图片描述

路由组件与一般组件

  1. 写法不同:
    • 一般组件:<Demo/>
    • 路由组件:<Route path="/demo" component={Demo}/>
  2. 组件存放的位置不同:
    • 一般组件:存放在components文件夹下
    • 路由组件:存放在pages文件夹下
  3. 接收到的props不同:
    • 一般组件:写组件标签时传递了什么,就能收到什么
    • 路由组件:接收到三个固定的属性
    history:
    	go: ƒ go(n)
    	goBack: ƒ goBack()
    	goForward: ƒ goForward()
    	push: ƒ push(path, state)
    	replace: ƒ replace(path, state)
    location:
    	pathname: "/about"
    	search: ""
    	state: undefined
    match:
    	params: {}
    	path: "/about"
    	url: "/about"
    

NavLink与封装NavLink

components/MyNavLink/index.jsx

import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
	render() {
		console.log(this.props);
		return (
			<NavLink activeClassName="zysheep" className="list-group-item" {...this.props}/>
		)
	}
}

  • NavLink可以实现路由链接的高亮,通过activeClassName指定样式名

使用:App.jsx

import React, { Component } from 'react'
import {Route} from 'react-router-dom'
import Home from './pages/Home' //Home是路由组件
import About from './pages/About' //About是路由组件
import Header from './components/Header' //Header是一般组件
import MyNavLink from './components/MyNavLink'

export default class App extends Component {
	render() {
		return (
			<div>
				<div className="row">
					<div className="col-xs-offset-2 col-xs-8">
						<Header/>
					</div>
				</div>
				<div className="row">
					<div className="col-xs-2 col-xs-offset-2">
						<div className="list-group">

							{/* 原生html中,靠<a>跳转不同的页面 */}
							{/* <a className="list-group-item" href="./about.html">About</a>
							<a className="list-group-item active" href="./home.html">Home</a> */}

							{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
							<MyNavLink to="/about">About</MyNavLink>
							<MyNavLink to="/home">Home</MyNavLink>
						</div>
					</div>
					<div className="col-xs-6">
						<div className="panel">
							<div className="panel-body">
								{/* 注册路由 */}
								<Route path="/about" component={About}/>
								<Route path="/home" component={Home}/>
							</div>
						</div>
					</div>
				</div>
			</div>
		)
	}
}

  • 标签体内容是一个特殊的标签属性
  • 通过this.props.children可以获取标签体内容

Switch的使用

import {Route,Redirect,Switch} from 'react-router-dom'
	
	<Switch>
	    <Route path="/insetScore" component={Context}/>
	    <Route path="/findScore" component={Message}/>
	    <Redirect to="/insetScore"/>
	</Switch>
  1. 通常情况下,path和component是一一对应的关系。
  2. Switch可以提高路由匹配效率(单一匹配)。

解决多级路径刷新页面样式丢失的问题

  1. public/index.html 中 引入样式时不写 ./ 写 / (常用)
  2. public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
  3. 使用HashRouter

路由的严格匹配与模糊匹配

  1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
  2. 开启严格匹配:<Route exact={true} path="/about" component={About}/>
  3. 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由

Redirect的使用

  1. 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
<Switch>
	    <Route path="/about" component={About}/>
	    <Route path="/home" component={Home}/>
	    <Redirect to="/about"/>
	</Switch>

嵌套路由

ex: Home组件下有News组件和Message组件

import React, { Component } from 'react'
import MyNavLink from '../../components/MyNavLink'
import {Route,Switch,Redirect} from 'react-router-dom'
import News from './News'
import Message from './Message'

export default class Home extends Component {
	render() {
		return (
				<div>
					<h3>我是Home的内容</h3>
					<div>
						<ul className="nav nav-tabs">
							<li>
								<MyNavLink to="/home/news">News</MyNavLink>
							</li>
							<li>
								<MyNavLink to="/home/message">Message</MyNavLink>
							</li>
						</ul>
						{/* 注册路由 */}
						<Switch>
							<Route path="/home/news" component={News}/>
							<Route path="/home/message" component={Message}/>
							<Redirect to="/home/news"/>
						</Switch>
					</div>
				</div>
			)
	}
}

  1. 注册子路由时要写上父路由的path值
  2. 路由的匹配是按照注册路由的顺序进行的

向路由组件传递参数

params参数

  • 路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
  • 注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
  • 接收参数:this.props.match.params
{/* 向路由组件传递params参数 */}
 <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> 

{/* 声明接收params参数 */}
<Route path="/home/message/detail/:id/:title" component={Detail}/> 

//Detail组件中接收params参数
const {id,title} = this.props.match.params 

search参数

  • 路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
  • 注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  • 接收参数:this.props.location.search
  • 获取到的search是urlencoded编码字符串,如(key=value&key=value),需要借助querystring解析(parse) (stringify)
import qs from 'querystring'
{/* 向路由组件传递search参数 */}
<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>

{/* search参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>

//Detail组件中接收search参数
const {search} = this.props.location
const {id,title} = qs.parse(search.slice(1))

state参数

  • 路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
  • 注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  • 接收参数:this.props.location.state
  • 注意:刷新也可以保留住参数
{/* 向路由组件传递state参数 */}
<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>

{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>

// 接收state参数
const {id,title} = this.props.location.state || {}

编程式路由导航

借助this.props.history对象上的API对操作路由跳转、前进、后退

params参数

this.props.history.push()+携带params参数

//push跳转+携带params参数
this.props.history.push(`/home/message/detail/${id}/${title}`)

{/* 声明接收params参数 */}
<Route path="/home/message/detail/:id/:title" component={Detail}/>

//Detail组件中接收params参数
const {id,title} = this.props.match.params 

this.props.history.replace+携带params参数

//replace跳转+携带params参数	
this.props.history.replace(`/home/message/detail/${id}/${title}`)
		
{/* 声明接收params参数 */}
<Route path="/home/message/detail/:id/:title" component={Detail}/>

//Detail组件中接收params参数
const {id,title} = this.props.match.params 

search参数

this.props.history.push()+携带search参数

//push跳转+携带search参数
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)

{/* search参数无需声明接收,正常注册路由即可 */}
Route path="/home/message/detail" component={Detail}/> 

//Detail组件中接收search参数
const {search} = this.props.location
const {id,title} = qs.parse(search.slice(1))

this.props.history.replace+携带search参数


//replace跳转+携带search参数
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)

{/* search参数无需声明接收,正常注册路由即可 */}
Route path="/home/message/detail" component={Detail}/> 

//Detail组件中接收search参数
const {search} = this.props.location
const {id,title} = qs.parse(search.slice(1))

state参数

this.props.history.push()+携带state参数

//push跳转+携带state参数
this.props.history.push(`/home/message/detail`,{id,title})

{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>

// 接收state参数
const {id,title} = this.props.location.state || {}

this.props.history.replace+携带state参数

//replace跳转+携带state参数
this.props.history.replace(`/home/message/detail`,{id,title})

{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>

const {id,title} = this.props.location.state || {}

withRouter的使用

withRouter可以加工一般组件,让一般组件具备路由组件所特有的API,withRouter的返回值是一个新组件

import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'

class Header extends Component {

	back = ()=>{
		this.props.history.goBack()
	}

	forward = ()=>{
		this.props.history.goForward()
	}

	go = ()=>{
		this.props.history.go(-2)
	}

	render() {
		console.log('Header组件收到的props是',this.props);
		return (
			<div className="page-header">
				<h2>React Router Demo</h2>
				<button onClick={this.back}>回退</button>&nbsp;
				<button onClick={this.forward}>前进</button>&nbsp;
				<button onClick={this.go}>go</button>
			</div>
		)
	}
}

export default withRouter(Header)

BrowserRouter与HashRouter的区别

  1. BrowserRouter没有任何影响,因为state保存在history对象中。
    底层原理不一样:
    • BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
    • HashRouter使用的是URL的哈希值。
  2. path表现形式不一样
    • BrowserRouter的路径中没有#,例如localhost:3000/demo/test
    • HashRouter的路径包含#,例如:localhost:3000/#/demo/test
  3. 刷新后对路由state参数的影响
    • BrowserRouter没有任何影响,因为state保存在history对象中。
    • HashRouter刷新后会导致路由state参数的丢失!!!
  4. 备注:HashRouter可以用于解决一些路径错误相关的问题。

react中使用axios

  1. 安装: cnpm i axios -D
  2. 导入使用
import axios from 'axios'

// get
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

// get带参数
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

// post请求
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});

react中解决跨域问题

在项目中,我使用了axios进行后端API请求,代码如下

 componentDidMount(){
      //没有请求参数
      axios.get('http://localhost:8080/api/getAllStudent')
      .then((response)=>{
          this.setState({data:response.data});
          console.info(response.data)
      })
      .catch((error)=>{
          console.log(error);
      });
  }

之所以可以请求到数据是因为我在后端允许跨域,而一般前后端分离开发是要前端人员自己配置跨域的。

解决方案:

  1. 使用第三方的WEB服务器Nginx做方向代理,解决跨域
  2. 在React-cli脚手架中修改配置信息解决跨域,有两种解决方案

React-cli配置代理解决跨域

方案一

在项目根目录的package.json中添加配置

"proxy":"http://localhost:8080"

在这里插入图片描述

这个方案配置起来较简单,前端请求资源时可以不加任何前缀。但是它的缺点很明显不能配置多个代理。

工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)

方案二

使用代理配置文件,在src下创建配置文件src/setupProxy.js,名字固定写法,不能更换,否则不生效。

const proxy = require('http-proxy-middleware')

module.exports = function(app) {
  app.use(
    proxy('/api1', {  //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
      target: 'http://localhost:8080', //配置转发目标地址(能返回数据的服务器地址)
      changeOrigin: true, //控制服务器接收到的请求头中host字段的值
      /*
      	changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
      	changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
      	changeOrigin默认值为false,但我们一般将changeOrigin值设为true
      */
      pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
    }),
    proxy('/api2', { 
      target: 'http://localhost:8081',
      changeOrigin: true,
      pathRewrite: {'^/api2': ''}
    })
  )
}

配置相比方案一较繁琐,前端请求资源时必须加前缀/api1或/api2。但是有点明显可以配置多个代理,可以很灵活的控制请求是否走代理。

  • 62
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李熠漾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值