最近在项目中出现了好多跨域的问题 写个回忆
简单说下跨域请求的发生:当 Web 资源请求由其它域名或端口提供的资源时,会发起跨域 HTTP 请求(cross-origin HTTP request)
问题描述
本次请求跨域主要发生在前端调用后端API上
会先发一个 Options
的预检请求 这个的返回一直过不去 导致真正的接口调用失败
在正式讲这个之前 需要讲一下简单请求和非简单请求
具体参考可以看 廖雪峰大神的博客 讲的很细很具体 点我走你
先来简单讲下 CORS(Cross-origin resource sharing) 跨域资源共享
他允许浏览器向本站以外的站点发起 XMLHttpRequest请求 说白就是你可以发送类似 Ajax 的请求,请求别人
浏览器一旦发现你是Ajax的跨域请求 会自动附加一些头信息 这个头信息决定了当前的请求是简单请求还是非简单请求
简单请求 (Simple Request)
在 Cors 中的简单请求
1.包含 GET
HEAD
POST
2.HTTP的头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
这样就是一个简单请求 简单会直接请求 服务器只要回复中允许 Origin
的源就可以了
非简单请求 (Not-so-Simple Request)
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。
只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错
关于Options请求
OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能
关于Http请求有8种 OPTIONS
、GET
、HEAD
、POST
、PUT
、DELETE
、TRACE
、CONNECT
其中最常用的莫过于 GET
和 POST
了
Options
请求主要实现2个功能
1.获取服务器支持的HTTP请求方法
2.用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全
为什么会产生 Options
请求?
因为浏览器发现你当前不是一个简单请求 在正式通信前发送了一次预检请求 也就是 Options
请求 来请求服务器允许的请求方法 和 一些Header头
服务器需要回复几个相关的字段就好了 如果没有这些字段 浏览器就会默认服务器不同意预检 后面的真正请求也就不会发出去 同时控制台可以看到类似的错误
XMLHttpRequest cannot load http://local.xxx.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
服务器方需要回复 下面的相关字段来应答 预检的 Options
请求
|
|
问题和基本概况已经讲解
因为后端 是使用的 Lumen
框架做的微服务 提供 API
给前端调用 我直接很暴力的加了个 Cors
的中间件给路由使用
CorsMiddleware.php
代码片段
|
|
然后在 Kernel.php
的 routeMiddleware
中 增加了如下配置
|
|
直接给Options
请求增加返回了上面的一个header头
但是最后发现并没有生效 因为这里只是声明了一个中间件的名字 而你需要在对应的请求路由设置 去引用这个中间件才能生效
然后在路由中加了中间件 还是发现没有生效 这时又发现了个问题 因为我的路由控制中都是写的post或get请求 即使你使用了中间件 他也只是会在对应的请求方式过来的时候才会去加载中间件 所以option请求过来是没有自动加载执行上面的中间件的 如果给每个请求都设置一次options的请求路由会累死啊 最后又去看了下Laravel文档 发现了一个解决办法
在Kennel.php
的
加载到这里的中间件才会全局执行 不论什么请求进来
至此解决了本次项目中的接口请求跨域问题
对框架理解还是不够深啊 加油!