• HTML网页中,img标签和Ajax请求是支持跳转(Redirect)的


    我们知道在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();
                }
                else
                {
                    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);
                }
                else
                {
                    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>
    
    <html>
    <head>
        <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>
    <body>
        <div>
            <h1>Index view!</h1>
        </div>
        <div>
            <button id="btnCallAjax" >调用ajax</button>
        </div>
        <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

  • 相关阅读:
    20171017/20171018
    BZOJ[3193] [JLOI2013]地形生成
    BZOJ[1009] [HNOI2008]GT考试
    BZOJ[4767] 两双手
    BZOJ[4013] [HNOI2015]实验比较
    BZOJ[1925] [Sdoi2010]地精部落
    20171015 杂题
    20171015
    20171014
    USACO 2015 December Contest, Gold Problem 3. Bessie's Dream
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/14308592.html
Copyright © 2020-2023  润新知