上篇文章,我们解析了301与302之间的区别,这篇文章,还是一如既往,通过实践的方式让大家去领会状态码302与303之间的区别。
需要注意,302状态码我们不会再去讲解,如果想了解301与302,请看这篇文章。
搭建环境
前端项目
执行以下命令:
// 1、创建项目
npx create-react-app font
// 2、进入到项目根目录
cd font
// 3、安装依赖
npm install
// 4、暴露配置
npm run eject
// 5、运行项目
npm run start
后端项目
执行以下命令:
// 1、第一步(安装express脚手架)
npm install -g express-generator
// 2、第二步(使用脚手架创建一个名为“end”的项目)
express end
// 3、第三步(进入项目目录)
cd end
// 4、第四步(安装项目依赖)
npm install
// 5、修改后端项目的端口号
// 6、第五步(启动项目)
npm run start
修改端口号的操作如下:
接着,我们来为本次的内容注册专门的路由:
修改routes目录下的users文件,修改后文件内容如下:
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.post('/303OldUrl', function(req, res, next) {
res.redirect(303, '/users/303NewUrl')
});
router.post('/303NewUrl', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
实现跨域资源共享
这个知识点在这里不做过多描述,进入到后端项目的目录下,安装cors模块,执行以下命令:
npm install cors
依赖安装成功后,修改项目根目录下的app.js文件如下:
好的,接下来,我们需要修改前端项目来测试这个ajax这个流程是否可以跑通。
新增Page页面,并且为这个页面单独开启一个路由,Page页面内容如下:
import React, { useState } from 'react';
import axios from 'axios';
import { Input, message } from 'antd';
function Page(props){
let [inputValue, setInputValue] = useState('');
const send303Req = () => {
let result = await axios.create({
baseURL: 'http://127.0.0.1:8888/'
})
.get('/users', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log('收到的响应:', response);
return response
})
.catch(function (error) {
console.log('响应出错了:', error);
return error;
});
if (result.status == 200){
message.success('收到了成功的响应!');
}
}
return <div className='page'>
<Input placeholder="请输入内容" value={inputValue}/>;
<button onClick={send303Req}>303</button>
</div>
}
export default Page;
分别启动前后端项目,项目全都启动成功后,我们在浏览器里输入:http://127.0.0.1:3000/page,
点击按钮发送请求,根据我们代码来看,如果返回成功200,并且页面上有一个提示框,那么前后端的流程就算成功的打通了。
303状态码
303 See Other(查看其他位置)。表示请求已经完成,但服务器应该告诉浏览器应该使用一个新的URL来访问资源,与302不同的是,此状态码要求后续请求使用GET方法来获取资源。
流程讲解
- 我们发送一个post请求,并且携带了请求体。
- 后端处理请求,返回303状态码,并且返回一个最新的资源地址。
- 浏览器使用
GET方法去请求最新的资源地址, 并且,浏览器会忽略掉第一次请求携带的请求体。 - 如果最新的资源地址是GET方法,那么浏览器将会收到成功的响应。
- 如果最新的资源地址是POST方法,那么浏览器将会收到404的响应。
动手实践
我们先来修改一下前端发送请求的地址为/users/303OldUrl,请求方式修改为post。
const send303Req = async () => {
let result = await axios.create({
baseURL: 'http://127.0.0.1:8888/'
})
.post('/users/303OldUrl', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log('收到的响应:', response);
return response
})
.catch(function (error) {
console.log('响应出错了:', error);
return error;
});
if (result.status == 200){
message.success('收到了成功的响应!');
}
if (result.status != 200){
message.error('请求地址404 ...');
}
}
根据后端的路由来看,这次请求的结果最终一定是个404,因为最新的资源地址是post方法,但是浏览器访问最新的资源地址是一个get请求。
此时我们如果来修改一下后端的最新资源的请求方法为GET,
当我们再次发送请求的时候,我们会发现此时是一个正常的响应,但是请求body依然会被干掉。
最后
其实如果你以同样的方式去测试302状态码的话,你会发现,302跟303状态码好像没区别,第二次请求都会被处理成get请求,请求体都会被废弃。那它俩有啥区别?
根据HTTP规范,302状态码在实际应用中经常被浏览器错误地处理为GET请求。
实际上,根据RFC 7231,当接收到302状态码时,客户端(浏览器)在遵循重定向时可以使用GET方法或者保持原始请求方法。但是,大多数浏览器会自动将POST请求转换为GET请求,这是由于历史上的一些安全和兼容性问题。
为了确保一致性和可预测性,HTTP/1.1引入了303状态码。当服务器返回303状态码时,客户端应该使用GET方法获取重定向的资源。所以根据标准,如果您希望在POST请求后进行重定向并期望客户端使用GET方法获取新的资源,应该返回303状态码。
最后的最后
好啦,本篇文章到这里就结束啦,如果本篇文章对你有帮助,欢迎一键四连。如果上述过程中有错误,也还请各路大神指正,那么,我们下期再见啦,👋👋👋。