如何使用React向Laravel应用程序发送POST请求
也许你是一个后端工程师,想使用React库向你的网站加载数据,或者你想探索React与Laravel的使用。或者你对使用Laravel与React有其他兴趣,无论如何,你都来对了地方。
我们将学习如何使用React向Laravel应用程序发出POST请求并获取响应。
基本描述
- React:这是一个JavaScript库,协助我们创建互动和动态的单页应用程序。
- Axios:这是一个库,用于处理网络应用中对外部资源的HTTP请求。
- Laravel:这是一个基于Model-View-Controller架构的PHP框架,帮助我们更快地创建Web后台应用程序。
前提条件
- 对PHP和如何使用Laravel有基本的了解。
- 对HTML和CSS有基本的了解。
- 对JavaScript有基本的了解,以及如何在React上使用。
- 在你的机器上安装有PHP, Composer, 和Laravel安装程序.
有了这些, 我们现在可以开始深入研究这个话题了。
我们将做什么
我们将从一个注册页面发送输入数据,并将数据发送到Laravel控制器,而控制器将返回JSON数据,并在警报中显示。
JSON, JavaScript Object Notation; 是一种Web应用程序之间的数据交换格式.
开始使用
我们通过在终端运行这个命令来创建我们的应用程序。
laravel new reactaxios
由于Laravel默认支持Vue.js,我们首先要用React.js替换Vue.js的支架。
php artisan preset react
创建控制器和路由
然后我们创建Laravel应用程序的控制器,接收POST请求。
php artisan make:controller AxiosReceiverController
打开控制器,添加以下代码。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AxiosReceiverController extends Controller
{
public function ReceiveIt(Request $request){
$validatedData = $request->validate([
'firstname' => 'nullable',
'lastname' => 'nullable',
'email' => 'nullable',
'phone' => 'nullable',
'NatID' => 'nullable',
'password' => 'nullable',
'userLevel' => 'nullable'
]);
return json_encode($validatedData);
}
}
该控制器包含一个方法ReceiveIt() ,它接收一个请求,根据用户规则进行验证,然后将其存储在一个名为$validatedData 的数组中。然后,它将数组作为JSON对象返回,我们将在后面检索。
然后我们在routes/web.php文件中为控制器创建一个路由。
Route::post('sendrequest', 'App\Http\Controllers\AxiosReceiverController@ReceiveIt');
建立React和Frontend模块
我们添加我们的应用程序的依赖性。
npm install
为了处理我们的路由,我们将使用React Router,为所有的路由渲染一个单一的视图。如果你有很多路由,这一点尤其重要。对于我们的情况,它将只有一个路由。
我们将在routes/web中创建一个通配符路由,其中的视图文件app.blade.php将被用来渲染我们的React组件。用下面的代码替换rouse/web中的视图代码。
Route::view('/{path?}', 'app');
我们前往resources/views目录,创建app.blade.php文件并添加以下代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<title>ReactAxios</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
我们引用了一个CSS文件和一个JavaScript文件,其中包含React和其他依赖性。我们有一个id为"app" 的空div,我们的组件将在这里被呈现。
接下来,我们在resources/js/components中创建App组件,名称为App.jsx,并删除默认存在的Example.js。
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import './App.css';
class App extends Component {
render () {
return (
<BrowserRouter>
<div>
<Switch>
</Switch>
</div>
</BrowserRouter>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
我们将安装React路由器,因为我们正在使用它。
npm install react-router-dom
在继续安装的同时,直接打开resources/js/中的app.js文件,用这个文件更新那里的代码。
require('./bootstrap')
require('./components/App')
注册页面
我们将在resources/js/components/目录下创建一个名为pages的文件夹,在这里我们将创建注册页面,将其命名为Register.jsx,并将其添加到该文件夹。在里面添加以下代码。
import React, { Component } from 'react';
import axios from "axios";
import wave from 'https://terrence-aluda.com/wave.png'
import bg from 'https://terrence-aluda.com/bg.svg'
import avatar from 'https://terrence-aluda.com/avatar.svg'
class Register extends Component {
constructor(props){
super(props);
this.state = {
firstname : '',
lastname : '',
email : '',
phone : '',
NatID : '',
password : '',
userLevel : 'Job Expert'
}
this.firstName = this.firstName.bind(this);
this.lastName = this.lastName.bind(this);
this.takePhone = this.takePhone.bind(this);
this.takeEmail = this.takeEmail.bind(this);
this.takeID = this.takeID.bind(this);
this.takePassword = this.takePassword.bind(this);
this.takeLevel = this.takeLevel.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
firstName(event){
this.setState({firstname : event.target.value})
}
lastName(event){
this.setState({lastname : event.target.value})
}
takePhone(event){
this.setState({phone : event.target.value})
}
takeEmail(event){
this.setState({email : event.target.value})
}
takeID(event){
this.setState({ID : event.target.value})
}
takePassword(event){
this.setState({password : event.target.value})
}
takeLevel(event){
this.setState({userLevel : event.target.value})
}
handleSubmit(){
const packets = {
firstname: this.state.firstname,
lastname: this.state.lastname,
email: this.state.email,
phone: this.state.phone,
NatID: this.state.ID,
userLevel: this.state.userLevel,
password: this.state.password
};
axios.post('/sendrequest', packets)
.then(
response => alert(JSON.stringify(response.data))
)
.catch(error => {
console.log("ERROR:: ",error.response.data);
});
}
render(){
return (
<div>
<img class="wave" src={wave} alt="img"/>
<div class="container">
<div class="img">
<img src={bg} alt="img"/>
</div>
<div class="login-content">
<form>
<img src={avatar} alt="img"/>
<h2 class="title">Register</h2>
<div class="input-div one">
<div class="i">
<i class="fas fa-user"></i>
</div>
<div class="div">
<h5></h5>
<input type="text" placeholder="First Name" onChange={this.firstName} class="input"/>
</div>
</div>
<div class="input-div one">
<div class="i">
<i class="fas fa-user"></i>
</div>
<div class="div">
<h5></h5>
<input type="text" placeholder="Last Name" onChange={this.lastName} class="input"/>
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class="fas fa-envelope-square"></i>
</div>
<div class="div">
<h5></h5>
<input type="email" placeholder="Email" onChange={this.takeEmail} class="input" />
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class=""></i>
</div>
<div class="div">
<select onChange={this.takeLevel} name="userLevel">
<option value="">Choose level</option>
<option value="Job Expert">Job Expert</option>
<option value="Client">Client</option>
</select>
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class="fas fa-id-card"></i>
</div>
<div class="div">
<h5></h5>
<input type="number" placeholder="National ID" onChange={this.takeID} class="input" />
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class="fas fa-phone"></i>
</div>
<div class="div">
<h5></h5>
<input type="number" placeholder="Phone Number" onChange={this.takePhone} class="input" />
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class="fas fa-lock"></i>
</div>
<div class="div">
<h5></h5>
<input type="password" placeholder="Password" onChange={this.takePassword} class="input" />
</div>
</div>
<div class="input-div pass">
<div class="i">
<i class="fas fa-lock"></i>
</div>
<div class="div">
<h5></h5>
<input type="password" placeholder="Confirm Password" class="input" />
</div>
</div>
<input type="submit" class="btn" onClick={this.handleSubmit} value="Register"/>
</form>
</div>
</div>
</div>
);
}
}
export default Register;
解释
我们引用我们将在页面上使用的图片。
然后构造函数初始化状态值并绑定组件的函数。
后续的函数用于在用户输入后从其调用的输入中取值,然后适当地设置状态值。
当提交按钮被点击时,handleSubmit() 函数被调用。该函数包含一个名为packets 的对象,其属性来自state 对象。然后在Axios的post方法中作为请求传给我们创建的Laravel控制器路由。
在请求之后,我们检索结果,并使用JSON.stringify() 方法在警报中显示,该方法将返回的对象转换为一个字符串。如果在这个过程中出现了错误,在被 "捕获 "后会显示在控制台。
为页面添加样式并更新App.jsx文件
对于样式,你可以自定义并添加你自己的样式,但我们将使用什么来格式化我们的页面,是在下面的CSS代码中。
打开resources/js/components/App.css,添加这段代码。
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200&family=Roboto:wght@100&display=swap');
:root{
--nav-width: 68px;
/* colors */
--first-color: #00BFA6/*#472347D9*/;
--first-color-light: #fff/*#AFA5D9*/;
--white-color: #F7F6FB;
/* === Font and Typography */
--body-font: 'Nunito', sans-serif;
--normal-font-size: 1rem;
/* z-index */
--z-fixed: 100;
}
body{
font-family: Nunito, sans-serif;
position: relative;
/* margin: var(--header-height) 0 0 0; */
margin: 0;
padding: 0;
font-family: var(--body-font);
font-size: var(--normal-font-size);
transition: .5s;
}
*, ::before, ::after{
box-sizing: border-box;
}
body::-webkit-scrollbar{
width: 8px;
}
body::-webkit-scrollbar-thumb{
background-color: rgb(36, 36, 36);
}
body::-webkit-scrollbar-track{
background-color: rgb(235, 236, 235);
}
.login-register{
display: flex;
justify-content: space-between;
}
.login-register a{
margin-right: 6px;
}
a{
text-decoration: none;
}
form {
background: white;
border: 1px solid #dedede;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 0 auto;
max-width: 500px;
padding: 30px 50px;
}
button{
border: none;
border-radius: 5px;
}
input,select {
border: 1px solid #d9d9d9;
border-radius: 4px;
box-sizing: border-box;
padding: 10px;
width: 100%;
}
label {
color: #3d3d3d;
display: block;
font-family: sans-serif;
font-size: 14px;
font-weight: 500;
margin-bottom: 5px;
}
li{
list-style: none;
margin: 0 10px;
}
/**Login**/
.wave{
position: fixed;
bottom: 0;
left: 0;
height: 100%;
z-index: -1;
}
.container{
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap :7rem;
padding: 0 2rem;
}
.img{
display: flex;
justify-content: flex-end;
align-items: center;
}
.login-content{
display: flex;
justify-content: flex-start;
align-items: center;
text-align: center;
}
.img img{
width: 500px;
}
form{
width: 360px;
}
.login-content img{
height: 100px;
}
.login-content h2{
margin: 15px 0;
color: #333;
text-transform: uppercase;
font-size: 2.9rem;
}
.login-content .input-div{
position: relative;
display: grid;
grid-template-columns: 7% 93%;
margin: 25px 0;
padding: 5px 0;
border-bottom: 2px solid #d9d9d9;
}
.login-content .input-div.one{
margin-top: 0;
}
.i{
color: #d9d9d9;
display: flex;
justify-content: center;
align-items: center;
}
.i i{
transition: .3s;
}
.input-div > div{
position: relative;
height: 45px;
}
.input-div > div > h5{
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
color: #999;
font-size: 18px;
transition: .3s;
}
.input-div:before, .input-div:after{
content: '';
position: absolute;
bottom: -2px;
width: 0%;
height: 2px;
background-color: #38d39f;
transition: .4s;
}
.input-div:before{
right: 50%;
}
.input-div:after{
left: 50%;
}
.input-div.focus:before, .input-div.focus:after{
width: 50%;
}
.input-div.focus > div > h5{
top: -5px;
font-size: 15px;
}
.input-div.focus > .i > i{
color: #38d39f;
}
.input-div > div > input{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: none;
outline: none;
background: none;
padding: 0.5rem 0.7rem;
font-size: 1.2rem;
color: #555;
font-family: 'poppins', sans-serif;
}
.input-div.pass{
margin-bottom: 4px;
}
a{
display: block;
text-align: right;
text-decoration: none;
color: #999;
font-size: 0.9rem;
transition: .3s;
}
a:hover{
color: #38d39f;
}
.btn{
display: block;
width: 100%;
height: 50px;
border-radius: 10px;
outline: none;
border: none;
background-image: linear-gradient(to right, #32be8f, #38d39f, #32be8f);
background-size: 200%;
font-size: 1.2rem;
color: #fff;
font-family: 'Poppins', sans-serif;
text-transform: uppercase;
margin: 1rem 0;
cursor: pointer;
transition: .5s;
}
.btn:hover{
background-position: right;
}
@media screen and (max-width: 1050px){
.container{
grid-gap: 5rem;
}
}
@media screen and (max-width: 1000px){
form{
width: 290px;
}
.login-content h2{
font-size: 2.4rem;
margin: 8px 0;
}
.img img{
width: 400px;
}
}
@media screen and (max-width: 900px){
.container{
grid-template-columns: 1fr;
}
.img{
display: none;
}
.wave{
display: none;
}
.login-content{
justify-content: center;
}
}
/**fire**/
.fa-fire{
color: rgb(255,102,102);
font-size: 3.8rem;
}
footer{
font-size: 1.5rem;
padding: 0.8rem;
text-align: center;
background-color: rgb(20, 20, 20);
color:#F7F6FB;
}
.dash{
background-color:#f2f4f6;
min-width: 60vw;
display: flex;
justify-content: center;
align-items: center;
}
.card-header{
background-color: #32be8f;
color: #fff;
}
.list-group-flush li:first-child{
font-size: 1.8rem;
color: blue;
text-decoration: underline;
}
.list-group-flush li:nth-child(2){
color: #6026ff;
font-size: 1.1rem;
font-weight: 500;
}
.list-group-flush{
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
我们用这段代码更新App.jsx 文件,以显示路线。
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import './App.css';
import RegisterPage from './pages/Register';
class App extends Component {
render () {
return (
<BrowserRouter>
<div>
<Switch>
<Route exact path='/' component={RegisterPage} />
</Switch>
</div>
</BrowserRouter>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
运行应用程序
在运行应用程序之前, 我们首先需要使用Laravel Mix来测试-编译反应,运行这个命令。
npm run dev
然后运行Laravel服务器:
php artisan serve
预期的输出。



结论
在本教程中, 我们了解了如何使用Axios库来发送一个HTTP请求.一个POST请求,用于使我们的应用程序RESTful。我们看到了JSON在后端和前端之间传递信息的用途。我将在其他教程中谈论使用这些技术的其他HTTP方法。
这就是目前的全部内容。希望你已经深入了解了如何使用Axios从React向Laravel应用程序发出POST请求。