浏览器 URL 在 POST 和 React - Node 应用程序中的 PATCH 表单操作之后更改
Browser URL changed after POST and PATCH form actions in React - Node app
首先,我要为一个很长的时间道歉post。我是初学者,这是一种我什至不确定如何 google 的行为。我会尽力解释。
我正在使用 Node、Express、React 和 Mongoose 构建一个简单的 CRUD 应用程序。我从后端开始,然后继续走向前端。将前端与后端连接后,我注意到了异常行为。例如,这是我的 postEditStudent
控制器:
exports.postEditStudent = (req, res, next) => {
console.log(req.params)
const id = req.params.id;
console.log('this is body', req.body)
Student.findByIdAndUpdate(mongoose.Types.ObjectId(id), {firstName : req.body.firstName, lastName : req.body.lastName})
.then((stud) => {
console.log('EDIT THIS GUY', stud);
return res.status(200).redirect('/')
})
.catch(err => console.log(err));
}
现在,为了到达那里,我们正在使用路由器:
const express = require('express');
const classController = require('../controllers/classController');
const router = express.Router();
router.get('/update/:id', classController.getEditStudent);
router.patch('/update/:id', classController.postEditStudent);
至于我的 server.js 页面,它是这样设置的:
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
const session = require('express-session');
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cors())
const classRoutes = require('./routes/class-routes');
const errorController = require('./controllers/error')
const MONGODB_URI = "mongodb+srv://this is a mongoose database path"
app.use('/teacher', authRoutes);
app.use('/class', classRoutes);
app.get('/', (req, res, next) => {
res.sendFile(path.resolve(__dirname, "../docs/index.html"))
next()
})
app.use(errorController.get404);
mongoose
.connect(MONGODB_URI)
.then(result => {
app.listen(3000);
console.log('CONNECTED')
})
.catch(err => {
console.log(err);
});
最后但并非最不重要的是,反应组件,神奇的地方:
class App extends Component {
constructor(props) {
super(props);
this.state = {
students: null,
edit: 'none',
add: 'block',
studentId: null,
firstName: '',
lastName: ''
};
}
handleFirstNameChange = (e) => {
this.setState({firstName: e.target.value});
console.log(this.state.firstName)
}
handleLastNameChange = (e) => {
this.setState({lastName: e.target.value});
}
editStudent = id => {
const requestOptions = {
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({firstName: this.state.firstName , lastName: this.state.lastName}),
};
console.log(id)
fetch("/class/update/" + id, requestOptions)
.then((response) => {
console.log('this is response')
return response.json();
})
.catch((err) => {
console.log(err)
})
}
render() {
if (!this.state.students) return null;
const studentNames = this.state.students.map(student => <Draggable bounds="parent" key={student.id}><div className="handle"><img onClick={() => this.getStudent(student.id)} className="imgLogo" src={user} alt="user-logo"/><div></div> {student.firstName}<div></div> {student.lastName}<div></div> <div><div></div><img onClick={() => this.showForm(student.id)} className="imgBox" src={edit} alt="edit-logo"/><img onClick={() => this.deleteStudent(student.id)} className="imgBox" src={trash} alt="delete-logo"/></div></div></Draggable>);
return (
<div className="float-container">
<divclassName="container float-child">{studentNames}
</div>
<div className="float-child">
<div><h4>Teacher:</h4><div></div><p>FIRSTNAME LASTNAME</p></div>
<h3>Student Info</h3>
<div id = "editForma">
<form>
<label >First Name:</label>
<input type="text" name="firstName" value={this.state.firstName} onChange={this.handleFirstNameChange} />
<div></div>
<br></br>
<label >Last Name:</label>
<input type="text" name="lastName" value={this.state.lastName} onChange={this.handleLastNameChange}/>
<button className="button button2" type="submit" onClick={() => this.editStudent(this.state.studentId)}>Edit Student</button>
</form>
</div>
</div>
</div>
);
}
}
export default App;
现在,当我选择要编辑的学生时,我将名字和姓氏编辑为“Kate”和“smith”,在请求过程结束时,我的页面转到 http://localhost:8080/?firstName=Kate&lastName=Smith
,这是我不明白的部分。
现在,一旦它导航到那里,即使我刷新页面并返回 http://localhost:8080/
,它也会“卡住”。
至于错误,我在 95% 的情况下都没有收到任何错误,只有一次我收到错误:
this is body { firstName: 'Kate', lastName: 'Smith' }
[1] MongoServerError: not primary
[1] at MessageStream.messageHandler (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/connection.js:462:30)
[1] at MessageStream.emit (node:events:390:28)
[1] at processIncomingData (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/message_stream.js:108:16)
[1] at MessageStream._write (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/message_stream.js:28:9)
[1] at writeOrBuffer (node:internal/streams/writable:390:12)
[1] at _write (node:internal/streams/writable:331:10)
[1] at MessageStream.Writable.write (node:internal/streams/writable:335:10)
[1] at TLSSocket.ondata (node:internal/streams/readable:777:22)
[1] at TLSSocket.emit (node:events:390:28)
[1] at addChunk (node:internal/streams/readable:324:12) {
[1] topologyVersion: { processId: new ObjectId("6226493d3f6cbc2e7ec62cd9"), counter: 54 },
[1] ok: 0,
[1] code: 10107,
[1] codeName: 'NotWritablePrimary',
[1] '$clusterTime': {
[1] clusterTime: new Timestamp({ t: 1647717344, i: 2 }),
[1] signature: {
[1] hash: new Binary(Buffer.from("c1c7efa296c48125954f75a0da484b63fd9a69de", "hex"), 0),
[1] keyId: new Long("7030875868872310785")
[1] }
[1] },
[1] operationTime: new Timestamp({ t: 1647717343, i: 1 }),
[1] [Symbol(errorLabels)]: Set(1) { 'RetryableWriteError' }
[1] }
您必须使用表单的属性 onSubmit 来传递您的请求处理函数。记得接收事件参数和运行'event.preventDefault()',以防止默认重定向和重定向行为
<form onSubmit={
onClick={(event) => {
event?.preventDefault()
this.editStudent(this.state.studentId)
}
}}>
<label >First Name:</label>
<input
type="text" name="firstName"
value={this.state.firstName}
onChange={this.handleFirstNameChange} />
<div></div>
<br></br>
<label >Last Name:</label>
<input
type="text"
name="lastName" value={this.state.lastName}
onChange={this.handleLastNameChange}/>
<button className="button button2" type="submit" >Edit Student</button>
</form>
如果您只将按钮的“类型”属性 更改为“按钮”而不是“提交”,也许它也能奏效。我从来没有这样做过,但也许它有效。
首先,我要为一个很长的时间道歉post。我是初学者,这是一种我什至不确定如何 google 的行为。我会尽力解释。
我正在使用 Node、Express、React 和 Mongoose 构建一个简单的 CRUD 应用程序。我从后端开始,然后继续走向前端。将前端与后端连接后,我注意到了异常行为。例如,这是我的 postEditStudent
控制器:
exports.postEditStudent = (req, res, next) => {
console.log(req.params)
const id = req.params.id;
console.log('this is body', req.body)
Student.findByIdAndUpdate(mongoose.Types.ObjectId(id), {firstName : req.body.firstName, lastName : req.body.lastName})
.then((stud) => {
console.log('EDIT THIS GUY', stud);
return res.status(200).redirect('/')
})
.catch(err => console.log(err));
}
现在,为了到达那里,我们正在使用路由器:
const express = require('express');
const classController = require('../controllers/classController');
const router = express.Router();
router.get('/update/:id', classController.getEditStudent);
router.patch('/update/:id', classController.postEditStudent);
至于我的 server.js 页面,它是这样设置的:
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
const session = require('express-session');
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cors())
const classRoutes = require('./routes/class-routes');
const errorController = require('./controllers/error')
const MONGODB_URI = "mongodb+srv://this is a mongoose database path"
app.use('/teacher', authRoutes);
app.use('/class', classRoutes);
app.get('/', (req, res, next) => {
res.sendFile(path.resolve(__dirname, "../docs/index.html"))
next()
})
app.use(errorController.get404);
mongoose
.connect(MONGODB_URI)
.then(result => {
app.listen(3000);
console.log('CONNECTED')
})
.catch(err => {
console.log(err);
});
最后但并非最不重要的是,反应组件,神奇的地方:
class App extends Component {
constructor(props) {
super(props);
this.state = {
students: null,
edit: 'none',
add: 'block',
studentId: null,
firstName: '',
lastName: ''
};
}
handleFirstNameChange = (e) => {
this.setState({firstName: e.target.value});
console.log(this.state.firstName)
}
handleLastNameChange = (e) => {
this.setState({lastName: e.target.value});
}
editStudent = id => {
const requestOptions = {
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({firstName: this.state.firstName , lastName: this.state.lastName}),
};
console.log(id)
fetch("/class/update/" + id, requestOptions)
.then((response) => {
console.log('this is response')
return response.json();
})
.catch((err) => {
console.log(err)
})
}
render() {
if (!this.state.students) return null;
const studentNames = this.state.students.map(student => <Draggable bounds="parent" key={student.id}><div className="handle"><img onClick={() => this.getStudent(student.id)} className="imgLogo" src={user} alt="user-logo"/><div></div> {student.firstName}<div></div> {student.lastName}<div></div> <div><div></div><img onClick={() => this.showForm(student.id)} className="imgBox" src={edit} alt="edit-logo"/><img onClick={() => this.deleteStudent(student.id)} className="imgBox" src={trash} alt="delete-logo"/></div></div></Draggable>);
return (
<div className="float-container">
<divclassName="container float-child">{studentNames}
</div>
<div className="float-child">
<div><h4>Teacher:</h4><div></div><p>FIRSTNAME LASTNAME</p></div>
<h3>Student Info</h3>
<div id = "editForma">
<form>
<label >First Name:</label>
<input type="text" name="firstName" value={this.state.firstName} onChange={this.handleFirstNameChange} />
<div></div>
<br></br>
<label >Last Name:</label>
<input type="text" name="lastName" value={this.state.lastName} onChange={this.handleLastNameChange}/>
<button className="button button2" type="submit" onClick={() => this.editStudent(this.state.studentId)}>Edit Student</button>
</form>
</div>
</div>
</div>
);
}
}
export default App;
现在,当我选择要编辑的学生时,我将名字和姓氏编辑为“Kate”和“smith”,在请求过程结束时,我的页面转到 http://localhost:8080/?firstName=Kate&lastName=Smith
,这是我不明白的部分。
现在,一旦它导航到那里,即使我刷新页面并返回 http://localhost:8080/
,它也会“卡住”。
至于错误,我在 95% 的情况下都没有收到任何错误,只有一次我收到错误:
this is body { firstName: 'Kate', lastName: 'Smith' }
[1] MongoServerError: not primary
[1] at MessageStream.messageHandler (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/connection.js:462:30)
[1] at MessageStream.emit (node:events:390:28)
[1] at processIncomingData (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/message_stream.js:108:16)
[1] at MessageStream._write (/Users/milospopovic/Desktop/Code/teacher-solo/node_modules/mongodb/lib/cmap/message_stream.js:28:9)
[1] at writeOrBuffer (node:internal/streams/writable:390:12)
[1] at _write (node:internal/streams/writable:331:10)
[1] at MessageStream.Writable.write (node:internal/streams/writable:335:10)
[1] at TLSSocket.ondata (node:internal/streams/readable:777:22)
[1] at TLSSocket.emit (node:events:390:28)
[1] at addChunk (node:internal/streams/readable:324:12) {
[1] topologyVersion: { processId: new ObjectId("6226493d3f6cbc2e7ec62cd9"), counter: 54 },
[1] ok: 0,
[1] code: 10107,
[1] codeName: 'NotWritablePrimary',
[1] '$clusterTime': {
[1] clusterTime: new Timestamp({ t: 1647717344, i: 2 }),
[1] signature: {
[1] hash: new Binary(Buffer.from("c1c7efa296c48125954f75a0da484b63fd9a69de", "hex"), 0),
[1] keyId: new Long("7030875868872310785")
[1] }
[1] },
[1] operationTime: new Timestamp({ t: 1647717343, i: 1 }),
[1] [Symbol(errorLabels)]: Set(1) { 'RetryableWriteError' }
[1] }
您必须使用表单的属性 onSubmit 来传递您的请求处理函数。记得接收事件参数和运行'event.preventDefault()',以防止默认重定向和重定向行为
<form onSubmit={
onClick={(event) => {
event?.preventDefault()
this.editStudent(this.state.studentId)
}
}}>
<label >First Name:</label>
<input
type="text" name="firstName"
value={this.state.firstName}
onChange={this.handleFirstNameChange} />
<div></div>
<br></br>
<label >Last Name:</label>
<input
type="text"
name="lastName" value={this.state.lastName}
onChange={this.handleLastNameChange}/>
<button className="button button2" type="submit" >Edit Student</button>
</form>
如果您只将按钮的“类型”属性 更改为“按钮”而不是“提交”,也许它也能奏效。我从来没有这样做过,但也许它有效。