Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSONP学习笔记 #11

Open
yyzclyang opened this issue May 30, 2018 · 0 comments
Open

JSONP学习笔记 #11

yyzclyang opened this issue May 30, 2018 · 0 comments

Comments

@yyzclyang
Copy link
Owner

yyzclyang commented May 30, 2018

1 JSONP诞生的由来

根据同源策略,当一个网站不能获取另外一个网站的数据,虽然这一策略能有效的保护网站隐私,但有时一些合理的用途需要用到不同网站之间的通讯,这就需要一些方式绕过同源策略。

于是就想着哪些方法可以获取其他网站的数据,开发者发现,html标签的src可以绕过同源策略,获取其他网站的数据,比如<iframe>、<img>、<script>

接下来说说<img>、<script>这两个标签是如何实现跨域的

2 <img>实现跨域

当利用JavaScript创建一个图片,并设置图片的src时,就一定会请求这个src,但是请求不支持POST,只能发起GET请求,代码如下:

let image = document.createElement('img')
img.src = 'http://www.yyzcl.com/pay'

通过上面的代码,就可以在网站上请求http://www.yyzcl.com/pay的数据,绕过同源策略实现了跨域

3 <script>实现跨域

同样的,script标签也可以实现跨域

let script = document.createElement('script')
script.src = 'http://www.yyzcl.com/pay'
//srcipt标签需要加入到页面中,才会发生请求
document.body.appendChild(script)
//每发出一次请求,就会在页面内生成一个script标签,需要清除
script.onload = function(e){
  e.currentTarget.remove()
}
script.onerror = function(e){
  e.currentTarget.remove()
}

如果在src中加入一个查询参数,并定义一个函数名为查询参数的函数,那么后端在接收到src发出的请求时,写一段调用这个函数的代码,返回给前端页面,前端页面就会执行这个函数

例如

//前端页面
window.pay = function(){

}
script.src = 'http://www.yyzcl.com/pay?callback=pay'

//后端代码
response.write(`${query.callback}.call(undefined,'需要传回的数据')`)

其实这就是JSONP了

JSONP

假设有两个网站,它们之间需要通讯

请求方:A站的前端页面(浏览器)
响应方:B站的后端(服务器)

请求方创建<script>,利用标签的src发出请求,同时加上一个查询参数?callback=X(X是自定义的)
响应方根据请求的查询参数callback,生成一段调用函数的JavaScript代码传给前端页面,例如:X.call(undefined,'需要传回的数据')
前端页面得到Javascript代码后,就会根据代码执行X.call(undefined,'需要传回的数据')

一般有如下约定:

使用callback作为查询参数的关键字
callback后面接的查询参数采取字母+随机数的命名方式,避免与其他函数名冲突

所以代码可以这么写

let functionName = 'pay' + parseInt(Math.random() * 10000, 10)
script.src = 'http://www.yyzcl.com/pay?callback=' + functionName
window[functionName] = function(){

}
//清除script标签、删除函数
script.onload = function(e){
  e.currentTarget.remove()
  delete window[functionName]
}
script.onerror = function(e){
  e.currentTarget.remove()
  delete window[functionName]
}

如果是用jQuery的话,可以这么写

$.ajax({
  url: 'http://fck.com:8000/receive',
  dataType: 'jsonp',
  success: function (response) {
    if (response === 'success') {
      amount.innerText = (amount.innerText - 0) + 1
    }
  }
})

简单的来说,JSONP就是利用<script>标签的src绕过同源策略,从别的网站获取一段JSON数据,callback后面的参数是页面存在的回调函数

@yyzclyang yyzclyang changed the title 2018.05.30 JSONP学习笔记 JSONP学习笔记 Aug 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant