cors跨域问题

CORS

CORS,全称Cross-Origin Resource Sharing,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。
CORS是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。
CORS也有一些限制,两种模型可以实现:
1.简单模型
支持get/post/put/delete请求,例如返回Access-Control-Allow-Origin:*,但是不允许自定义header且会忽略cookies,且post数据格式有限制,只支持‘text/plain’,‘application/x-www-urlencoded’and’multipart/form-data’,其中’text/plain’默认支持,后面两种需要下面的预检请求和服务器协商。
2.协商模型/预检请求(Preflighted Request)
举例:浏览器发出PUT请求,OPTION请求返回Access-Control-Allow-Origin:
,Access-Control-Allow-Methods:’PUT’,服务器同意所有域的PUT请求,浏览器收到并继续发出真正的PUT请求,服务器响应并再次返回Access-Control-Allow-Origin:
,允许浏览器的脚本执行服务器返回的数据。

跨域请求:发起请求的域和该请求指向的资源所在域不同,只要协议、域名、端口有一个不同就是跨域请求浏览器地址栏中的协议域名端口,与网页中使用js请求的协议域名端口有一者不同就是跨域。

测试

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demotitle>
head>
<body>
<h1 id="json">h1>
<script>
    function doit() {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost/json');
        xhr.send();
    }
script>
<input type="button" value="点我测试跨域问题" onclick="doit()">
body>
html>
func JsonGet() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, gin.H{
			"message": "返回json数据",
		})
	}
}

运行JsonGet然后用浏览器打开html文件。点击"点我测试跨域问题"按钮,页面数据产生。打开浏览器控制台。可见出现了跨域问题。
cors跨域问题_第1张图片

两种Gin框架解决办法

使用jsonp

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demotitle>
head>
<body>
<h1 id="json">h1>
<h1 id="jsonp">h1>

<script>
    function doit() {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost/json');
        xhr.send();
    }

    function write(obj) {
        document.getElementById("jsonp").innerText = 'cors:'+JSON.stringify(obj);
    }
script>
<input type="button" value="点我测试跨域问题" onclick="doit()">
<script src="http://localhost/jsonp?callback=write">script>
body>
html>

运行jsonpGet,然后用浏览器打开html文件。回调了函数write对h1标签进行了赋值操作。

cors跨域问题_第2张图片

使用中间件

package middleware

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func Cors() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		method := ctx.Request.Method

		ctx.Header("Access-Control-Allow-Origin", "*")
		ctx.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token")
		ctx.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT")
		ctx.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
		ctx.Header("Access-Control-Allow-Credentials", "true")

		if method == "OPTIONS" {
			ctx.AbortWithStatus(http.StatusNoContent)
		}
	}
}

Reference
https://baike.baidu.com/item/CORS/16411212?fr=aladdin

你可能感兴趣的:(#,gin,jsonp,跨域,cors)