前言:

today的面试知识点:前后端交互相关,涉及到跨域,cookie session token 以及相对应DOM和ajax 

面试引导上面,应该讲自己的成长经历,从前后端联调,然后引入跨域问题,然后在引出cookie和session

 

目录

1. 跨域是什么?

1.1 CORS的处理方式?

1.1.1 cors简单请求 和非简单请求处理不一样

1.1.2 Head请求是什么?

2. Springboot 后端解决跨域的代码


1. 跨域是什么?

如果有人问这个问题,怎么样才能完美回答呢?

Q:什么是跨域?

A:浏览器有一个同源策略,为了保护用户的信息安全.

Q:什么样的情况不是同一域?

  • http或者https之类的协议不相同,即属于跨域。
  • 不同域名属于跨域(包括二级)
  • 端口不一致也属于跨域

Q:同源策略的概念和具体限制?

A:同源策略:限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。(来自MDN官方的解释)

源包括三个:包括协议,域名和端口。Http协议的默认端口是80.

限制:这个源的文档没有权限去操作另一个源的文档。

  1. Cookie、LocalStorage和IndexDB无法获取。(我可以理解成携带的信息Cookie无法获取)
  2. 无法获取和操作DOM。不能发送Ajax请求。(DOM在前端有什么用?)
  3. Ajax只适合同源的通信。

Q:前后端如何通信?

A:应该说就是用AJAX

Ajax:不支持跨域。

WebSocket:不受同源策略的限制,支持跨域。

CORS:不受同源策略的限制,支持跨域。一种新的通信协议标准。可以理解成是:同时支持同源和跨域的Ajax。

Q:AJAX是什么?

AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

 

Q:POST请求与GET请求的区别

总结:get会被浏览器记忆,cache

而post则是不会保存参数,每次都会再次提交

Post支持多种字符集,而get只支持ASCII编码

get会把请求参数放在URL上面,而post放在Request body里面

所以Post更加安全

get 参数放在url上,以?分割url,参数之间以&相连;英文/数字,不做改变,原样发送

get、post 都是tcp 连接。

get 一般来说提交的数据最大是2k;(原则上url 长度无限制,但大多数浏览器通常都会限制url 长度在2k(2048字节byte))

post 理论上没有限制,实际上IIS4中最大量为80k,IIS5中为100k。

get 产生一个tcp 数据包,浏览器会把http header 和data 一并发送出去,服务器响应200(返回数据)

post 产生两个tcp 数据包,浏览器会先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200(返回数据)

100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新) 

Q:DOM的含义?

用于页面渲染。

1.1 CORS的处理方式?

CORS需要浏览器和服务器同时支持。因为现在ie10以上,绝大多数浏览器都支持。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。

所以是浏览器一但发现请求跨域,然后就会自动加上一些附加的头信息。

所以CORS就是服务器实现就好了。

1.1.1 cors简单请求 和非简单请求处理不一样

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:(可以认为头信息比较少的比较基本的)

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

简单请求,浏览器要是跨域的话,直接发出一个CORS请求,就是在头信息中增加一个Origin字段

GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

那么Origin字段用来说明请求来自哪个源(协议+域名+端口),服务器根据这个值,决定是否同意这次请求

如果被服务器拒绝了,这个指定的源不在服务器允许的范围里面,那么就会返回一个正常的HTTP回应。

头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

许可的话:
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

与CROS请求相关的字段,都以Access-Control-开头。

至于我们平时都用json

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

所以是非简单请求。

1.1.2 Head请求是什么?

HEAD: 只请求页面的首部。(基本也没见过)

 

参考:https://baijiahao.baidu.com/s?id=1615806554906953063&wfr=spider&for=pc

跨域资源共享 CORS 详解 : http://www.ruanyifeng.com/blog/2016/04/cors.html

2. Springboot 后端解决跨域的代码

使用CORS。

解决的思路就是:允许同源的三要素,都换成*

修改CorsConfiguration

源:origin

头:header (这边应该包含了端口)

允许任何的方法:post get

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
        corsConfiguration.addAllowedHeader("*"); // 2允许任何头
        corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
}