我们知道在HTTP请求中,状态码301和302代表跳转,也叫重定向(Redirect)。
301-Moved Permanently
:永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替。
302-Found
:临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI。
参考
HTTP状态码
。
我们知道一个常规的HTTP请求(例如请求一个网页),是支持跳转(Redirect)的。经过实验发现,其实HTML网页上的img标签和Ajax请求,也是会自动处理HTTP跳转(Redirect)的。
我们新建一个ASP.NET Core MVC项目AspNetCoreRedirectDemos,本文的例子基于ASP.NET Core 5.0项目。
下面是项目中HomeController的代码:
using AspNetCoreRedirectDemos.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
namespace AspNetCoreRedirectDemos.Controllers
public class HomeController : Controller
private readonly ILogger<HomeController> _logger;
private readonly bool redirectPicture = true;//图片请求是否跳转,true表示进行跳转
private readonly bool redirectAjax = true;//Ajax请求是否跳转,true表示进行跳转
public HomeController(ILogger<HomeController> logger)
_logger = logger;
public IActionResult Index()
return View();
public IActionResult ShowFirstPicture()
if (!redirectPicture)
string path = AppDomain.CurrentDomain.BaseDirectory + "Files\\1.jpg";
byte[] data = null;
using (FileStream fs = new FileStream(path, FileMode.Open))
data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
Response.ContentType = "image/jpeg";
Response.ContentLength = data.Length;
using (Stream stream = Response.Body)
stream.Write(data, 0, data.Length);
return new EmptyResult();
return RedirectToAction("ShowSecondPicture");//将访问ShowFirstPicture这个Action方法的请求,跳转到Action方法ShowSecondPicture
public IActionResult ShowSecondPicture()
string path = AppDomain.CurrentDomain.BaseDirectory + "Files\\2.jpg";
byte[] data = null;
using (FileStream fs = new FileStream(path, FileMode.Open))
data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
Response.ContentType = "image/jpeg";
Response.ContentLength = data.Length;
//Action方法ShowSecondPicture,返回图片2.jpg到客户端浏览器
using (Stream stream = Response.Body)
stream.Write(data, 0, data.Length);
return new EmptyResult();
public IActionResult FirstAjaxResponse([FromBody] PersonRequestModel personRequestModel)
if (!redirectAjax)
ResponseData responseData = new ResponseData()
StatusCode = 100,
Message = "奔驰,返回消息"
return Json(responseData);
return RedirectToAction("SecondAjaxResponse");//将访问FirstAjaxResponse这个Action方法的请求,跳转到Action方法SecondAjaxResponse
public IActionResult SecondAjaxResponse()
ResponseData responseData = new ResponseData()
StatusCode = 100,
Message = "宝马,返回消息"
//Action方法SecondAjaxResponse,返回json数据到客户端浏览器
return new JsonResult(responseData);
我们在HomeController中,定义了ShowFirstPicture和ShowSecondPicture两个Action方法,HTML网页上的img标签会请求ShowFirstPicture方法获取图片数据流,而ShowFirstPicture方法会返回HTTP状态码302到客户端浏览器,让浏览器发送新的HTTP请求,跳转(Redirect)到ShowSecondPicture方法,然后ShowSecondPicture方法会返回图片文件2.jpg的数据到客户端浏览器,供img标签显示。
我们还在HomeController中,定义了FirstAjaxResponse和SecondAjaxResponse两个Action方法,HTML网页上的JavaScript代码会发送Ajax请求给FirstAjaxResponse方法,而FirstAjaxResponse方法会返回HTTP状态码302到客户端浏览器,让浏览器发送新的HTTP请求,跳转(Redirect)到SecondAjaxResponse方法,然后SecondAjaxResponse方法会返回JSON数据到客户端浏览器。
此外,我们还在HomeController中定义了两个bool类型的变量redirectPicture和redirectAjax,分别用来控制是否启用img标签和Ajax请求的跳转(Redirect),当变量值为true时,就表示启用跳转(Redirect)。
下面是HomeController的Index.cshtml视图文件代码:
Layout = null;
<!DOCTYPE html>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/lib/jquery/dist/jquery.js" ></script>
<script type="text/javascript" >
$(function () {
$("#btnCallAjax").click(function () {
var ajaxData = {};
ajaxData.Name = "王大锤, Jack Wang";
ajaxData.Age = 38;
$.ajax({
type: "POST",
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "@Url.Action("FirstAjaxResponse")",
data: JSON.stringify(ajaxData),
success: function (data) {
alert(JSON.stringify(data))
error: function (xhr, ts, et) {
alert('服务调用失败!');
</script>
</head>
<h1>Index view!</h1>
</div>
<button id="btnCallAjax" >调用ajax</button>
</div>
<img src="@Url.Action("ShowFirstPicture")" />
</div>
</body>
</html>
我们可以看到在视图代码中,使用了img标签和Ajax代码,来请求了HomeController的ShowFirstPicture和FirstAjaxResponse两个Action方法。
接下来我们运行项目,跟踪浏览器的HTTP请求日志,来看看发生了什么:
从上面截图中,我们可以看到浏览器在加载Index.cshtml视图文件生成的HTML网页后,img标签首先发出了HTTP请求到Action方法ShowFirstPicture,然后ShowFirstPicture方法返回了HTTP状态码302,告诉浏览器需要进行HTTP跳转(Redirect),所以img标签又发起了第二次HTTP请求到Action方法ShowSecondPicture,然后ShowSecondPicture方法返回了HTTP状态码200,将图片数据返回给了浏览器显示,符合我们的预期。
接下来我们点击浏览器网页上的"调用ajax"按钮,来触发Ajax请求,继续跟踪浏览器的HTTP请求日志:
从上面截图中,我们可以看到JavaScript代码首先发出了Ajax请求到Action方法FirstAjaxResponse,然后FirstAjaxResponse方法返回了HTTP状态码302,告诉浏览器需要进行HTTP跳转(Redirect),所以浏览器又发出了第二个Ajax请求到Action方法SecondAjaxResponse,然后SecondAjaxResponse方法返回了HTTP状态码200,将JSON数据返回给了浏览器显示,这说明Ajax也是可以自动处理HTTP跳转(Redirect)的。但是需要注意的是,我们看到第一次到Action方法FirstAjaxResponse的Ajax请求是POST的,但是第二次到Action方法SecondAjaxResponse的Ajax请求变成了GET的了,说明Ajax在自动处理HTTP跳转(Redirect)的时候,始终是用GET方法来发起跳转请求的,所以在实际开发中,不建议让Ajax来自动处理HTTP跳转(Redirect),而应该使用JavaScript代码来重新发起一个新的Ajax请求到跳转后的地址。
本文通过例子来演示了在HTML网页上,img标签和Ajax请求是可以自动处理HTTP跳转(Redirect)的,但是Ajax会始终用GET方法来发起跳转请求,所以不推荐让Ajax来自动处理HTTP跳转(Redirect)。
本文示例ASP.NET Core MVC项目下载:
AspNetCoreRedirectDemos