为什么postman调接口不会跨域而浏览器会

为什么postman调接口不会跨域而浏览器会?
  • 都在说跨域,为什么postman能访问接口,而浏览器就不行呢?这里需要理解什么是跨域,跨域是指的当前资源访问其他资源时发起的http请求由于安全原因(由于同源策略,域名、协议。端口中只要有一个不同就不同源),浏览器限制了这些请求的正常访问,特别需要注意的是这些发生在浏览器中。而通过postman等工具调用接口时,只是简单的访问一个资源,并不存在资源的相互访问。
知识预热
  • 回调函数
    • 这里就不细讲回调函数啦,相信各位都能理解,用一个案例来说一下。
    • “服务器”和“客户端”初次相识,相谈甚欢,客户端希望服务器把一个叫json的东西给它,”服务器“:你先忙着,我弄好了发给你,把你电话号码(回调函数)给我。
  • 跨域中的预检请求即是指浏览器在真正发送请求前,会先发送一个Options请求嗅探,请求成功后才会发送真实的请求。问答三连:
    • 为什么需要发送预检请求?是因为触发了浏览器的安全校验。
    • 为什么请求会触发安全校验?因为当前请求是一个"复杂请求"。
    • 为什么我的请求是“复杂的”?见下面解释
  • 复杂和简单请求
    • 简单请求:请求方法是GET/HEAD/POST,并且contentType为text/plain、application/x-www-form-urlencoded、multipart/form-data。
    • 不满足上述条件的视为复杂请求,开发中我们常触发这个条件大多因为我们的请求的contentType设置的是application/json导致的。
    • 简单请求如果设置了Authentication认证header也会让请求“升级”为复杂请求。
理解spring提供的@CrossOrigin注解
@CrossOrigin(maxAge = 3600,origins = "*")

  • @CrossOrigin可以放在某个方法上,或者放在类上,这样对类中所有请求方法有效,指定能访问的域集合,即是设置Access-Control-Allow-Origin。
  • maxAge 属性指定了预检请求的缓存时间,单位是秒。对应http的Access-Control-Max-Age属性
    • 缓存的内容为:Access-Control-Allow-Methods和Access-Control-Allow-Headers 提供的信息。
理解使用jsonp解决跨域问题
  • 上面简单介绍了回调函数,jsonp是如何解决跨域的呢?其实就是利用了一个特性,html页面中引入不同域的js是不会引发跨域的,下面的案例中,我引入了一个在线的query地址,并且在script标签的src写上了后端的接口地址,从前端的角度我们可以想象成只是简单请求一个js文件,js文件的内容是一个函数调用,刚好浏览器本地定义了这个函数,所以请求完毕,就会对这个函数发起调用,当然前后端的函数名需要一样,这就是我们说的回调函数的机制。
前端

	
	
	
	
		

init...

-------------------------------------------------------------------------------- 后端: /** * 返回 使用回调函数包裹的json * @return */ @RequestMapping("/infoWithCallBack") public String info(){ JSONObject map = new JSONObject(); map.put("msg","请求成功!"); map.put("code","0000"); map.put("data","获取到后端数据!"); String str = map.toString(); return "myCallback(" + str + ")"; }
  • 上面的例子在正常返回的json前面包裹了一个函数名,为的是能让浏览器执行,如果不采用jsonp的方式,而是后端设置Access-Control-Allow-Origin,则请求到的不是一个标准json,所以我们需要改造一下,兼容两种方式。
	
--------------------------------------------------------------------------------
 /**
     * 3.兼容jsonp和普通json请求
     * @return
     */
    @RequestMapping("/info3")
    public String info3(@RequestParam(name="callback",required = false) String callBack){
        JSONObject map = new JSONObject();
        map.put("msg","请求成功!");
        map.put("code","0000");
        map.put("data","获取到后端数据!");
        String result = map.toString();
        if(!StringUtils.isEmpty(callBack)){
            //如果是json请求,则包裹上回调函数
            return callBack + "(" + result + ")";
        }
        return result;
    }
其他遇到的问题
Uncaught SyntaxError: Unexpected token :
  • 在解决跨域时,遇到这种错误,一般是前端没有设置回调函数,而后端返回了被回调函数包裹的json.
info?callback=callback:1 Uncaught ReferenceError: callback is not defined
    at info?callback=callback:1
  • 回调函数未定义,请求后端接口的script标签必须在声明的回调函数之后定义,否则会报错。

  • 代码已push到侠梦的github,https://github.com/Hyq0823/Stardust/tree/master/src/main/java/com/cors
    为什么postman调接口不会跨域而浏览器会_第1张图片

你可能感兴趣的:(网页html-css)