HTML页面加载导致Javascript在重定向页面中无法正常运行

时间:2018-10-08 19:24:34

标签: javascript c# jquery html asp.net-mvc

我的主页按钮未在get请求中添加标题,因此出现此问题。我将令牌存储在localStorage内部,并在向Controller:Home Action:Index发出get请求时将其发送到标头中。据我所知,它不使用我的jquery,直接进入帐户/索引。

起初,我虽然没有将JavaScript绑定到按钮单击上,但还是有问题。经过进一步调查,我发现_Layout.cshtml中的Console.log()不起作用,该按钮也不起作用。这使我相信Login.js文件中的$("html").html(response);存在问题。

正确的流程是LoginPage-> Login.js(获取数据并使用Ajax进行发布请求。)->返回由_Layout.cshtml和/Views/Home/Index.cshtml组成的html页面

以下是文件“ Views / Shared / _Layout.cshtml”的代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Chat </title>

        <environment include="Development">
            <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
            <link rel="stylesheet" href="~/css/site.css" />
        </environment>
        <environment exclude="Development">
            <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
                  asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
                  asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
            <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
        </environment>
    </head>
    <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li id="li_btnHome"><a asp-area="" asp-controller="" asp-action="">Home</a></li>
                </ul>
            </div>
        </div>
    </nav>


        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; 2018 - Chat</p>
            </footer>
        </div>

        <environment include="Development">
            <script src="~/lib/jquery/dist/jquery.js"></script>
            <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
            <script src="~/js/site.js" asp-append-version="true"></script>
            <script type="text/javascript">
                console.log("Development");
            </script>
        </environment>
        <environment exclude="Development">
            <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
                    asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                    asp-fallback-test="window.jQuery"
                    crossorigin="anonymous"
                    integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
            </script>
            <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                    asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                    asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                    crossorigin="anonymous"
                    integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
            </script>
            <script src="~/js/site.min.js" asp-append-version="true"></script>
            <script type="text/javascript">
                console.log("Not Development");
            </script>
        </environment>
        <script type="text/javascript">
            console.log("Hello World");
        </script>
        <!--<script src="~/js/NavBarFunction.js"></script>-->
        @RenderSection("Scripts", required: false)
    </body>
</html>

这是JavaScript文件“ wwwroot / js / NavBarFunctions.js”:

    $("#li_btnHome a")[0].onclick = function (event) {
event.preventDefault();
alert("called click");
var tokenObj = localStorage.getItem("token");
var tokenStr = tokenObj == null ? "what_about_tokenObj_is_null?" : tokenObj.toString();
$.ajax({
    type: 'GET',
    contentType: 'application/json; charset=utf-8;',
    url: '@Url.Action("Index", "Home")',
    beforeSend: function (xhr) {
        xhr.setRequestHeader("Authorization", tokenStr);
    },
    success: function (response) {
        alert(1);
        $("html").html(response);
    }
});
return false;
};

这里是HomeController,位于“控制器/ HomeController”中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Chat.Enums;
using Chat.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;

namespace _Chat.Controllers
{
    public class HomeController : Controller
    {
        private AuthenticateUser authenticateUser = new AuthenticateUser();

        public async Task<IActionResult> Index()
        {
            var request = Request;
            var headers = request.Headers;

            StringValues token;
            if (headers.TryGetValue("Authorization", out token))
            {
                var result = await this.authenticateUser.ValidateToken(token);
                if (result.Result == AuthenticateResult.Success)
                {
                    return View();
                }
                else
                {
                    return RedirectToAction("Index", "Account");
                }
            }

            return RedirectToAction("Index", "Account");
        }
    }
}

出于某种奇怪的原因,我的页面从登录重定向到首页后,所有脚本/ javascript都停止了工作。

这是验证登录名的代码。位于“ Controllers / AccountController”中:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Chat.Models;
using Chat.DatabaseAccessObject;
using Chat.Identity;
using Chat.DatabaseAccessObject.CommandObjects;
using System.Linq.Expressions;
using System.Net.Mime;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens;

namespace Chat.Controllers
{
    public class AccountController : Controller
    {
        private const string SECRET_KEY = "CHATSECRETKEY";
        public static SymmetricSecurityKey SIGNING_KEY = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SECRET_KEY));
        private ServerToStorageFacade serverToStorageFacade = new ServerToStorageFacade();
        private AuthenticateUser authenticateUser = new AuthenticateUser();

        public IActionResult Index()
        {
            return View();
        }

        // Post: /login/
        [HttpPost]
        public async Task<IActionResult> Login([FromBody]LoginModel loginModel)
        {
            if (ModelState.IsValid)
            {
                var mapLoginModelToUser = new MapLoginModelToUser();
                var user = await mapLoginModelToUser.MapObject(loginModel);

                // If login user with those credentials does not exist
                if(user == null)
                {
                    return BadRequest();
                }

                else
                {
                    var result = await this.authenticateUser.Authenticate(user);

                    if(result.Result == Chat.Enums.AuthenticateResult.Success)
                    {
                        // SUCCESSFUL LOGIN
                        // Creating and storing cookies

                        var token = Json(new
                        {
                            data = this.GenerateToken(user.Email, user.PantherID),
                            redirectUrl = Url.Action("Index","Home"),
                            success = true
                        });
                        return Ok(token);
                    }
                    else
                    {
                        // Unsuccessful login
                        return Unauthorized();
                    }
                }
            }

            return BadRequest();
        }

        private string GenerateToken(string email, string pantherId)
        {
            var claimsData = new[] { new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Actor, pantherId) };

            var signInCredentials = new SigningCredentials(SIGNING_KEY, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                issuer: "localhost",
                audience: "localhost",
                expires: DateTime.Now.AddDays(7),
                claims: claimsData,
                signingCredentials: signInCredentials
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public async Task<IActionResult> Error() => View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }

    public class MapLoginModelToUser
    {
        private ServerToStorageFacade serverToStorageFacade;

        public MapLoginModelToUser()
        {
            serverToStorageFacade = new ServerToStorageFacade();
        }


        public async Task<User> MapObject(LoginModel loginModel)
        {
            Expression<Func<User, bool>> expression = x => x.Email == loginModel.inputEmail;

            var user = await this.serverToStorageFacade.ReadObjectByExpression(new User(Guid.NewGuid()), expression);

            if(user == default(Command))
            {
                return null;
            }

            return new User(user.ID)
            {
                Email = loginModel.inputEmail,
                Password = loginModel.inputPassword,
                FirstName = user.FirstName,
                LastName = user.LastName,
                PantherID = user.PantherID,
                ClassDictionary = user.ClassDictionary,
                UserEntitlement = user.UserEntitlement
            };
        }
    }
}

还有呈现页面的代码。位于“ wwwroot / js / Login.js”中:

$(document).ready(function () {
    $("#formSubmit").submit(function (event) {
        event.preventDefault();
        var email = $("#inputEmail").val();
        var password = $("#inputPassword").val();
        var remember = $("#rememberMe").val();
        var loginModel = {
            inputEmail: email,
            inputPassword: password,
            rememberMe: remember
        };

        $.ajax({
            type: 'POST',
            url: 'Account/Login',
            data: JSON.stringify(loginModel),
            contentType: 'application/json; charset=utf-8;',
            success: function (response) {
                var token = response.value.data;
                localStorage.setItem("token", token);
                alert("You have successfully logged in.");
                setHeader();
                redirect(response.value.redirectUrl);
            }
        });
    });

    function setHeader() {
        $.ajaxSetup({
            beforeSend: function (xhr) {
                xhr.setRequestHeader('Authorization', localStorage.getItem("token"));
            }
        });
    }

    function redirect(redirectUrl) {
        $.ajax({
            type: 'GET',
            contentType: 'application/json; charset=utf-8;',
            url: redirectUrl,
            success: function (response) {
                $("html").html(response);
            }
        });    
    }
});

这是加载新的html页面后收到的错误: Console Redirect Error

编辑:这是单击“主页”按钮后在响应中发送的内容。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Login - Chat FIU</title>


            <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.css" />
            <link rel="stylesheet" href="/css/site.css" />


    </head>
    <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a id="btnHome" href="/">Home</a></li>
                </ul>
            </div>
        </div>
    </nav>


        <div class="container body-content">


<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="/css/signin.css" rel="stylesheet">
    <script src="/lib/jquery/dist/jquery.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="/js/Login.js"></script>
</head>
<body class="text-center">
    <form id="formSubmit" method="post" class="form-signin">
        <img class="mb-4" src="/images/FIU-Chat-Curved.png" alt="" width="150" height="150">
        <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
        <label for="inputEmail" class="sr-only">Email address</label>
        <input autofocus="" class="form-control" data-val="true" data-val-required="The Email field is required." id="inputEmail" name="inputEmail" placeholder="Email address" required="required" type="email" value="" />
        <label for="inputPassword" class="sr-only">Password</label>
        <input class="form-control" data-val="true" data-val-required="The Password field is required." id="inputPassword" name="inputPassword" placeholder="Password" required="required" type="password" />
        <div class="checkbox mb-3">
            <label>
                <input data-val="true" data-val-required="The Remember field is required." id="rememberMe" name="rememberMe" type="checkbox" value="true" />  Remember me
            </label>
        </div>
        <button id="btnLogin" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
        <p class="mt-5 mb-3 text-muted">&copy; 2017-2018</p>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Ah5tOyN_3lPrH0DgSEU8vD7Q7JItdizW-mYDc5uamCO3oRTBN-pdo9ZyPgRaHRyovwEGfT5Qhw0UD-rfbIHUJPt4FgUOhM1OkAWC9AtAfPEKkxz7TBfwKfz0EpfxF4DX2DAczujogr__xnIr3vDq3o" /><input name="rememberMe" type="hidden" value="false" /></form>

</body>
</html>
            <hr />
            <footer>
                <p>&copy; 2018 - Chat FIU</p>
            </footer>
        </div>


            <script src="/lib/jquery/dist/jquery.js"></script>
            <script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
            <script src="/js/site.js?v=BxFAw9RUJ1E4NycpKEjCNDeoSvr4RPHixdBq5wDnkeY"></script>
            <script type="text/javascript">
            </script>


        <script type="text/javascript">
        </script>
        <script src="/js/NavBarFunction.js"></script>

    </body>

1 个答案:

答案 0 :(得分:0)

解决问题的关键在您的流程中,如下所述:

  

正确的流程是LoginPage-> Login.js(获取数据并使用Ajax   (用于发布请求。)->返回由以下内容组成的html页面   _Layout.cshtml和/Views/Home/Index.cshtml

这种流程意味着您要重定向到索引页(通过在控制器操作中使用return RedirectToAction("Index", "Account");来证明),该AJAX在GET方法中的重定向使用没有任何意义(因为AJAX调用旨在留在同一页面)。

不是使用$("html").html(response);替换整个HTML页面内容,而是使用window.location.href使用指定的URL重定向,如下所示:

NavBarFunctions.js

$("#li_btnHome a")[0].click(function (event) {
    event.preventDefault();
    alert("called click");
    var tokenObj = localStorage.getItem("token");
    var tokenStr = tokenObj == null ? "what_about_tokenObj_is_null?" : tokenObj.toString();

    $.ajax({
        type: 'GET',
        url: '@Url.Action("Index", "Home")',
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Authorization", tokenStr);
        },
        success: function (response) {
            // this is just an example, replace action & controller name as you wish
            window.location.href = '@Url.Action("ActionName", "ControllerName")';
        }
    });
});

Login.js

function redirect(redirectUrl) {
    $.ajax({
        type: 'GET',
        contentType: 'application/json; charset=utf-8;',
        url: redirectUrl,
        success: function (response) {
            window.location.href = redirectUrl;
        }
    });    
}

但是,如果要使用部分视图呈现页面的特定部分,则可以使用jQuery.html()定位占位符,例如<div>标记:

<!-- partial view placeholder -->
<div id="content">...</div>
// ajax callback
$.ajax({
    // other settings
    .....
    success: function (response) {
        $('#content').html(response);
    },
    .....
});