Go中beego解决跨域问题 利用cors,史上最详细

golang的优势就是做微服务,但是暴露出来的api不在同一个项目中调用会报错?

No 'Access-Control-Allow-Origin' header is present on the requested

包括前端处理了跨域请求jsonp但是还是没用!

接下来小飞哥带大家解决这个问题

go get "github.com/astaxie/beego/plugins/cors"  如果没用go环境 请看上个博客如何安装

安装成功后我们在main.go中加入以下代码

首先引入cors

import( "github.com/astaxie/beego/plugins/cors")

然后加入以下代码

func main() {
    //InsertFilter是提供一个过滤函数
	beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
        //允许访问所有源
		AllowAllOrigins: true,
        //可选参数"GET", "POST", "PUT", "DELETE", "OPTIONS" (*为所有)
        //其中Options跨域复杂请求预检
		AllowMethods:   []string{"*"},
        //指的是允许的Header的种类
		AllowHeaders: 	[]string{"*"},
        //公开的HTTP标头列表
		ExposeHeaders:	[]string{"Content-Length"},
        //如果设置,则允许共享身份验证凭据,例如cookie
		AllowCredentials: true,
	}))
	beego.Run()
}

然后启动项目调用api这个时候就可以解决啦

接下来为大家解释为什么这样写就可以了

首先介绍 CROS跨域:

       CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
要了解CROS跨域,首先需要知道浏览器在ajax发起跨域请求的时候做了什么事。每次浏览器检查到这个请求是跨域请求时,会在请求的头部加上一些头信息根据我们请求不同,浏览器发起的请求也不同有时候可能是多次请求,但是这些用户是感觉不到,前端的ajax调用也没有发什么变化,改变的是服务器端的回应。所以cros跨域由于浏览器的支持,现在只要在服务器端,也就是后端进行配置就可以了。

cros跨域请求有俩种 :一种是简单请求,一种的非简单请求,两种的区别就是在发起非简单请求的时候,浏览器会在请求的前面先发起一次预请求,看请求的后端是否允许当前这个域名和这个方法进行访问。

那么我们怎么给他分类呢?

简单请求:

简单请求(不满足以下条件的都是非简单请求):
(1)请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded 或 multipart/form-data 或text/plain

对于简单请求的cros跨域请求,浏览器会在就是在头信息之中,增加一个Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)服务器根据这个值,决定是否同意这次请求。
如果Origin的字段在服务器端允许的范围内,服务器成功响应,会在返回的头信息中多几个字段

//该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
Access-Control-Allow-Origin: http://api.bob.com
//该字段可选。它的值是一个布尔值,表示是否允许发送Cookie
Access-Control-Allow-Credentials: true
//该字段可选。
Access-Control-Expose-Headers: FooBar

如果Origin指定的域名不在许可范围内。服务器也会正常的返回HTTP的回应(状态吗有可能是200),只是头信息里面不会增加上面的字段。浏览器收到回应后 会检测是否有Access-Control-Allow-Origin字段,如果没有回抛出一个错误,被XMLHttpRequest的onerror回调函数捕获

非简单请求:

非简单请求就是不满足简单请求条件的都是非简单请求,值得注意的是Content-Type: application/josn都是非简单请求。
浏览器如果检测到发起的请求是非简单请求,会在正式发起HTTP请求前,浏览器会自动发起一次HTTP查询请求,称为”预检”请求(preflight)。
预请求的方法是OPTIONS,这个方法和GET,POST等方法是一样的。这个方法表示请求是用来询问的服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

一个预检请求
OPTIONS /cors HTTP/1.1
//表示请求来自哪个源。
Origin: http://api.bob.com
//该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,这个是PUT。
Access-Control-Request-Method: PUT
//该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
预检请求允许,服务器端的回应
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
//表示http://api.bob.com可以请求数据。该字段也可以设为*,表示同意任意跨源请求。
Access-Control-Allow-Origin: http://api.bob.com
//该字段必需,表明服务器支持的所有跨域请求的方法。
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain;
预检请求被否定时,跟简单请求一样会回复一个正常的HTTP请求,然后浏览器检查,被被XMLHttpRequest对象的onerror回调函数捕获就会报错
XMLHttpRequest cannot load http://api.alice.com.
Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.

一旦服务器通过了”预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。

发布了15 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36546907/article/details/88357887