• 重定向Http status code 303 和 302


    1. http 302
    2. http 303

    Http 302

    302是一个普通的重定向代码。直观的看来是,请求者(浏览器或者模拟http请求)发起一个请求,然后服务端重定向到另一个地址。而事实上,服务端仅仅是增加一条属性到header,location=重定向地址。而一般的,浏览器会自动的再去请求这个location,重新获取资源。也就是说,这个会使得浏览器发起两次请求。

    Example

    Client request:

    GET /index.html HTTP/1.1
    Host: www.example.com

    Server response:

    HTTP/1.1 302 Found
    Location: http://www.iana.org/domains/example/

    实验

    1. 首先,我们用一个Map来存储信息,key为username,value为随机数。
    2. 当我请求list的时候,跳转到users,来获取所有的用户。
    
    Map<String, Double> users = new HashMap<>();
    
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String index(){
        return "redirect:/users";
    }
    
    @ResponseBody
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public ResponseEntity getUsers(){
        ResponseEntity responseEntity = new ResponseEntity(users, HttpStatus.OK);
        return responseEntity;
    }   
    
    

    当时用浏览器访问的时候,会明显的看到浏览器地址变了,也就是说我明明请求的是list,结果你给我变成了users。然而,由于浏览器帮我们做了跳转的工作,我们感觉不出来,但从地址栏还是可以看到的。

    查看
    通过拦截请求可以看出来,访问了两次:

    并且list是302,而users是200.也就是说list进行了重定向。再来看list的response:

    Request URL:https://localhost:8443/list
    Request Method:GET
    Status Code:302 
    Remote Address:127.0.0.1:8888
    
    Response Headers
    view source
    Cache-Control:no-cache, no-store, max-age=0, must-revalidate
    Content-Language:zh-CN
    Content-Length:0
    Date:Thu, 08 Sep 2016 14:31:33 GMT
    Expires:0
    Location:https://localhost:8443/users
    Pragma:no-cache
    Strict-Transport-Security:max-age=31536000 ; includeSubDomains
    X-Application-Context:application:dev:8443
    X-Content-Type-Options:nosniff
    X-Frame-Options:DENY
    X-XSS-Protection:1; mode=block
    
    Request Headers
    view source
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding:gzip, deflate, sdch, br
    Accept-Language:zh-CN,zh;q=0.8
    Authorization:Basic YWRtaW46dGVzdA==
    Connection:keep-alive
    Host:localhost:8443
    Upgrade-Insecure-Requests:1
    User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
    

    最关键的就是location:

    Location:https://localhost:8443/users
    浏览器获取到这个资源定位后就GET访问获取。所以users的请求是这样的:

    Request URL:https://localhost:8443/users
    Request Method:GET
    Status Code:200 
    Remote Address:127.0.0.1:8888
    
    **Response Headers**
    view source
    Cache-Control:no-cache, no-store, max-age=0, must-revalidate
    Content-Type:application/json;charset=UTF-8
    Date:Thu, 08 Sep 2016 14:31:33 GMT
    Expires:0
    Pragma:no-cache
    Strict-Transport-Security:max-age=31536000 ; includeSubDomains
    Transfer-Encoding:chunked
    X-Application-Context:application:dev:8443
    X-Content-Type-Options:nosniff
    X-Frame-Options:DENY
    X-XSS-Protection:1; mode=block
    
    **Request Headers**
    view source
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding:gzip, deflate, sdch, br
    Accept-Language:zh-CN,zh;q=0.8
    Authorization:Basic YWRtaW46dGVzdA==
    Connection:keep-alive
    Host:localhost:8443
    Upgrade-Insecure-Requests:1
    User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
    

    redirect的另一个作用是原请求的内容将会被舍弃,即如果是post请求,redirect的时候默认是不带参数的。与之相对应的forward的请求是转发,只有一次请求,并且带body转发过去。


    Http 303

    303 See Other。通常是指所请求的资源在别的地方,并且同302一样,会在header中的location标明资源的位置。在我的一个是使用过程中,我想要创建一个user,当关于这个user的key已经存在的时候,server将返回303,并且告之这个user的获取位置。

    Example
    Client request:

    POST / HTTP/1.1
    Host: www.example.com

    Server response:

    HTTP/1.1 303 See Other
    Location: http://example.org/other

    实验

    我将要发送post请求创建user,如果user已经存在则返回303

    
        Map<String, Double> users = new HashMap<>();
    
        @ResponseBody
        @RequestMapping(value = "/users", method = RequestMethod.POST)
        public ResponseEntity createUser(String username){
            Double luckNum = users.get(username);
            if (luckNum ==null){
                double random = Math.random();
                users.put(username, random);
                return new ResponseEntity(random,HttpStatus.OK);
            }else{
                MultiValueMap<String,String> headers = new HttpHeaders();
                headers.add("Location", "/users/"+username);
                return new ResponseEntity(luckNum, headers, HttpStatus.SEE_OTHER);
            }
        }
    
        @ResponseBody
        @RequestMapping(value = "/users/{username}", method = RequestMethod.GET)
        public ResponseEntity getUser(@PathVariable("username") String username){
            ResponseEntity responseEntity = new ResponseEntity("I'm user, My name is  "+ username+ " And my luck num is "+users.get(username), HttpStatus.OK);
            return responseEntity;
        }
    

    发送

    查看拦截

    可以看到,post的时候返回303,并且在返回的response的header中添加了:

    Location: /users/test

    所以see other的意思就是去别的地方看看。值得注意的是,如果返回303,但是没有添加location,那么只会查看一条请求303.而在httpclient的默认处理中,这时候会抛出exception:location not found。

    参考

  • 相关阅读:
    LeetCode算法题-Convert Sorted Array to Binary Search Tree(Java实现)
    LeetCode算法题-Binary Tree Level Order Traversal II(Java实现)
    LeetCode算法题-Maximum Depth of Binary Tree
    LeetCode算法题-Symmetric Tree(Java实现)
    LeetCode算法题-Same Tree(Java实现)
    基于任务的异步编程模式,Task-based Asynchronous Pattern
    Nito.AsyncEx 这个库
    暴力 六点钟
    夜晚 十点 React-Native 源码 暴力畜 系列
    夜晚 暴力 十点钟 jQuery 的 extend 实现 原理
  • 原文地址:https://www.cnblogs.com/woshimrf/p/http-code-302.html
Copyright © 2020-2023  润新知