环境
- window 10
- asp.net core 3.1
一、先说下结论
当浏览器向后台发起请求时,后台返回302,此时浏览器因为请求的发起方式不同,处理302的方式也不同,下面列举常见的处理方式:
请求方式 | 浏览器处理 | Header变化 | Cookie变化 | Body变化 |
---|---|---|---|---|
ajax-get/fetch-get | 自动重定向,js代码感知不到,页面不会跳转 | 除cookie外,header无变化 | 不发送cookie(原地址和目标地址的都不会发送) | get中无body |
ajax-post/fetch-post | 自动重定向,post变get,js代码感知不到,页面不会跳转 | 同上 | 同上 | body丢失 |
form-get | 自动重定向,所在页面跳转 | 无自定义header | 可发送目标地址cookie | 无body |
form-post | 自动重定向,所在页面跳转 | 无自定义header | 可发送目标地址cookie | body丢失 |
iframe src | 自动重定向,但frame的src上还显示跳转前的地址 | 无自定义header | 同host则发送,否则不发送cookie | 无body |
img src | 自动重定向,但img的src上还显示跳转前的地址 | 无自定义header | 同host则发送,否则不发送cookie | 无body |
css background-url | 自动重定向 ,但url()上还显示跳转前的地址 | 无自定义header | 同host则发送,否则不发送cookie | 无body |
a href | 自动重定向 | 无自定义header | 可发送目标地址cookie | 无body |
二、测试的前端代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="jquery-2.1.4.js"></script>
</head>
<body>
<button onclick="get401()">get-401</button>
<button onclick="getredirect()">ajax-get</button>
<button onclick="postredirect()">ajax-post</button>
<script>
function get401() {
$.get("/demo/Get401");
}
//get请求由浏览器自动重定向,重定向后,header里面的自定义内容不丢失(cookie不会传递,原地址和目标地址的cookie都不会带上)
function getredirect() {
$.ajax({
type: "get",
async: true,
url: "/demo/getredirect",
headers: {
"Test-Header": "test-header"
}
}).done(res => {
console.log("getredirect=>", res);
}).fail(err => {
console.error("getredirect=>", err);
})
}
//post请求由浏览器重定向,重定向后method改为get,header里面的自定义内容不丢失(cookie不会传递,原地址和目标地址的cookie都不会带上),但body中的内容被丢弃
function postredirect() {
$.ajax({
type: "post",
async: true,
url: "/demo/postredirect",
contentType: "application/json",
headers: {
"Test-Header": "test-header"
},
data: JSON.stringify({
name: "小明",
age: 20
})
}).done(res => {
console.log("postredirect=>", res);
}).fail(err => {
console.error("postredirect=>", err);
})
}
</script>
<hr />
<button onclick="fetch_get_redirect()">fetch-get</button>
<button onclick="fetch_post_redirect()">fetch-post</button>
<script>
//get请求由浏览器自动重定向,重定向后(cookie不会传递,原地址和目标地址的cookie都不会带上),header里面的自定义内容不丢失
function fetch_get_redirect() {
fetch("/demo/fetchGetRedirect", {
headers: {
"Test-Header": "test-header"
}
}).then((response) => {
console.log(response.status);
console.log(response.statusText);
console.log(response.headers.get('Location'));
return response.text();
}).then(data => console.log(data)).catch(e => console.log('error' + e));
}
//post请求由浏览器重定向,重定向后method改为get,header里面的自定义内容不丢失(cookie不会传递,原地址和目标地址的cookie都不会带上),但body中的内容被丢弃
function fetch_post_redirect() {
fetch("/demo/fetchPostRedirect", {
method: "post",
headers: {
"Content-Type": "application/json",
"Test-Header": "test-header"
},
body: JSON.stringify({
name: "小明",
age: 20
})
}).then((response) => {
console.log(response.status);
console.log(response.statusText);
console.log(response.headers.get('Location'));
return response.text();
})
.then(data => console.log(data))
.catch(e => console.log('error' + e));
}
</script>
<hr />
<form action="/demo/formGet" method="get">
<input type="hidden" name="username" value="xiaoming" />
<input type="submit" value="form-get" />
</form>
<!-- form的post重定向后,post变get,body内容丢失,此时会带上目标地址的cookie -->
<form action="/demo/formPost" method="post">
<input type="hidden" name="username" value="xiaoming" />
<input type="submit" value="form-post" />
</form>
<hr />
<iframe src="/demo/iframe"></iframe>
<hr />
<img src="/demo/imgredirect" style="max-width:100px" />
<hr />
<style>
.bg {
background-image: url('/demo/imgredirect');
background-size: 100%;
background-position: center;
background-repeat: no-repeat;
width: 100px;
height: 57px;
}
</style>
<div class="bg"></div>
<a href="demo/getredirect">超链接</a>
</body>
</html>
三、测试的后端代码:
namespace RedirectTest.Controller
{
[Route("[controller]/[action]")]
public class DemoController : ControllerBase
{
[HttpPost]
public IActionResult PostRedirect()
{
//
//var refer = Request.Headers["Referer"];
//return Redirect(refer);
return Redirect("http://localhost:9090/test.html");
}
[HttpGet]
public IActionResult GetRedirect()
{
//return Redirect("http://localhost:9090/test.html");
return Redirect("http://a.site.com:9090/test.html");
}
[HttpGet]
public IActionResult fetchGetRedirect()
{
return Redirect("http://localhost:9090/test.html");
}
[HttpPost]
public IActionResult fetchPostRedirect()
{
return Redirect("http://localhost:9090/test.html");
}
[HttpGet]
public IActionResult Get401()
{
return new UnauthorizedResult();
}
[HttpGet]
public IActionResult FormGet()
{
return Redirect("http://localhost:9090/test.html");
}
[HttpPost]
public IActionResult FormPost()
{
//可以在hosts文件中修改配置,使用form的post方法重定向后,重定向的请求会自动带上目标地址的cookie
return Redirect("http://a.site.com:9090/test.html");
//return Redirect("http://localhost:9090/test.html");
}
public IActionResult IFrame()
{
return Redirect("http://localhost:9090/test.html");
//return Redirect("http://a.site.com:9090/test.html");
}
public IActionResult ImgRedirect()
{
//return Redirect("http://localhost:9090/test.jpg");
return Redirect("http://a.site.com:9090/test.jpg");
}
[HttpGet]
public IActionResult GetCookie()
{
Response.Cookies.Append("test-cookie", "123");
return Ok("ok");
}
}
}