一、同源政策
Ajax请求限制:
Ajax 请求时,浏览器要求当前网页和服务器必须同源。
什么是同源:
如果两个页面拥有相同的协议、域名、端口,那么这两个页面就属于一个源,其中只要有一个不相同,就是不同源。
同源政策的目的:
同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。
最初的同源政策就是指A网站在客户端设置的Cookie,B网站是不能访问的。随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发生Ajax请求,如果请求,浏览器就会报错。(实际上Ajax会被发送出去,但是浏览器会拒绝接受服务器的响应,所以会失败)
二、使用JSONP解决同源限制问题
jsonp 是 json with padding 的缩写,它不属于Ajax请求,但是它可以模拟Ajax请求。
jsonp实际上就是绕过浏览器同源请求的限制,向非同源服务器发送请求。
核心:利用script标签的src属性不受同源政策的影响来完成请求,它属于get请求。
同样不受同源政策影响的还有link标签、img标签的src属性。
第一步(客户端):将非同源的服务器端地址写在script标签的src属性中
1 | <script src="www.example.com"></script> |
1)在浏览器端,并不是所有能够发送请求的途径都受同源政策的限制,例如script标签的src属性就拥有发送请求的能力,但却不受同源政策的影响。例如我们在引入jquery时,就可以写线上的jquery文件地址。
2)请求地址不一定需要以 .js 结尾。但是不管请求地址以什么结尾,都必须返回合法的js代码。因为script标签在加载完请求地址中的内容以后,会将内容作为js代码来执行。
第二步(服务器端):服务器端响应的数据必须是一个函数的调用,真正要发生给客户端的数据需要作为函数调用的参数
1 | const data = 'fn({name:"张三", age:"20"})' |
浏览器端通过script标签将响应内容加载完毕以后,会自动将响应内容作为js代码来执行。
实际上,响应内容加载完毕后,会立即调用fn这个函数,因为加载过来的内容就是函数调用的代码。
服务器端响应的必须是一个字符串,字符串中包裹着函数调用的代码。如果没有被字符串包裹,这个函数会在服务器端被执行,而实际上我们要让它在客户端被执行。还要将客户端真正需要的数据,写在函数的实参里,因为函数在客户端被执行的时候,客户端可以通过形参来对应这个数据。
也就是说,客户端可以通过函数的形参拿到服务器端返回的真正数据。
需要注意,这个函数是在客户端被执行,因此客户端要事先准备好这个函数的定义,具体看第三步。
第三步(客户端):在客户端全局作用域下定义函数fn( ),并在fn函数内部对服务器响应的数据进行处理
1 | <script> |
客户端完整实例:
1 | <script> |
后续会写对 JSONP 代码进行优化的内容~~