同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同

当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。

如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

同源

域名、协议、端口相同,也就是在同一个域里。

非同源受到的限制

  • cookie不能读取 (如我在自己的站点无法读取博客园用户的cookie)

  • dom无法获得

  • ajax请求不能发送

什么是浏览器跨域

例如:

一个域的页面去请求另一个域的资源;

A域的页面去请求B域的资源。

😀 Jsonp实现跨域

JSONP的基本原理

动态添加一个标签,而script标签的src属性是没有跨域的限制的。

这样一来,这种跨域方式就与ajax XmlHttpRequest协议无关了。

JSONP即JSON with Padding

由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。

如果要进行跨域请求, 我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象,这种跨域的通讯方式称为JSONP。

JSON 是一种数据格式

JSONP 是一种数据调用的方式

Jsonp的执行过程

首先在客户端注册一个callback (如:'TestJsonpCallback'), 然后把callback的名字(如:testjsonpcallback)传给服务器。

注意:

服务端得到callback的数值后,要用TestJsonpCallback(......)把将要输出的json内容包括起来,此时,服务器生成 json 数据才能被客户端正确接收。
然后以 javascript 语法的方式,生成一个function, function 名字就是传递上来的参数 'callback'的值 TestJsonpCallback.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数, 传入到了客户端预先定义好的 callback 函数.

Try one test

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/static/jquery-3.4.1.js"></script>

</head>
<body>
<h1>index</h1>


<p>
    <input type="button" onclick="Jsonp1();" value='jsonp1'/>
</p>

<script>


    function Jsonp1() {
        let url = 'http://127.0.0.1:8088/jsonp/success';
        $.ajax({
            type: 'get',
            dataType: 'jsonp',
            url: url,
            //这个是后台接受的参数
            jsonp: "jsonpCallback",
            success: function (res) {
               console.log(res)
            },
            error (err) {
                console.error(err)
            }
        })
    }
</script>
</body>
</html>

Spring boot web

package cn.boommanpro.jsonp.controller;

import org.springframework.web.bind.annotation.*;

/**
 * @author wangqimeng
 * @date 2020/1/6 11:16
 */
@RestController
@CrossOrigin("*")
@RequestMapping("jsonp")
public class JsonpController {

    @GetMapping("success")
    public String listByName(@RequestParam String jsonpCallback) {
        return jsonpCallback + "(" + "{\"data\":\"SUCCESS\"}" + ")";
    }
}


Yapi测试编写

var cb = params.jsonpCallback;
if (!cb){
    cb = 'callback';
}

var json = {
  "result": [
    {
      "lng": "121.542306",
      "lat": "29.865646"
    }
  ]
}

var res = JSON.stringify(json);
mockJson = cb + '(' + res + ')';