Ajax是会受到同源的影响的,当我们要使用非同源的资源的时候,就会报错,所以说Ajax只能获取同源的资源。
但是有解决办法让Ajax获取不同源的资源,需要遵循CORS机制。需要服务器给响应当中有一个“Access-Control-Allow-Origin”字段,如果响应中没有这个字段的话,就会报错。
1. 什么是CORS
cross-origin resource sharing(CORS)跨域资源共享,是一种使用额外HTTP首部实现跨域获取资源权限的机制。
header(“Access-Control-Allow-Origin: *”); 这句话的意思是服务器允许哪个源向我这里获取数据,如果不设置的话,只能允许同源的来获取数据。(这里的 * 表示的是允许所有的源都可以来我这里获取数据。)
这里也可以设置固定的某一些域,比如:header(“Access-Control-Allow-Origin: http://localhost”);表示的是只能“http://localhost”下面的源能访问,其他的源访问的话就不允许了。
2. CORS分类
2.1 简单请求
- 使用下列方法之一:
a. GET
b. POST
c. HEAD - content-Type值为下列之一:
a. text/plain
b. multipart/form-data
c. application/x-www-form-urlencoded等
除了正常发起请求外,若想实现cors跨域,还需要服务器配置正确的响应首部。否则无法获取
access-contral-allow-origin: *(http://localhost) 访问控制允许源。
注意:需同时满足上面两个条件才是一个简单请求。
2.2 预检请求
“需预检的请求”要求必须首先使用OPTIONS(查询支持的方法
)方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求(如使用DELETE请求,那么它首先会发起一个请求(其实就是预检请求),先向服务器中去问一下,你是否允许DELETE请求,如果允许的话那么我再发送一个请求,才能正式的去DELETE)。
预检请求是需要发送两次请求的,一次是*OPTIONS请求,还有一次才是正式的我们想要发送的请求。
“预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:
1. 使用非GET POST HEAD方法
2. content-Type值不为下列之一:
a. text/plain
b. multipart/form-data
c. application/x-www-form-urlencoded
3. 人为设置了 CORS 安全的首部字段集合之外的首部字段,如人为的写一个CORS安全的首部字段集合(xml.setRequestHeader(‘X-user’,’daipi173′);):https://fetch.spec.whatwg.org/#cors-safelisted-request-header
例如:发起POST请求,人为设置了X-user:daipi173字段,则需要预检请求。此时就需要服务器设置正确的字段:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Request-Methods: POST,GET,PUT,DELETE,OPTIONS"); //实际请求所允许使用的HTTP方法
header("Access-Control-Allow-Headers: X-user, content-type"); //请求中允许携带的首部字段
header("Access-Control-Max-Age: 86400"); //请求的结果能够被缓存,可以不用设置,不设置的话就是一个临时缓存
注意:如果当你再一次发送的话,它就不会帮你预检了。因为发送的请求已经预检过了,并且是符合的,那么你发送请求的时候它就不帮你再预检了。
CORS跨域,前端需要做的事情其实是很少的,更多的是后端与我们前端来进行一个配合。