关于 JSONP 及 CORS 绕过同源策略的原理解释

JSONP 跨域

JSONP 的全名叫做 JSON Padding

  • 其出现的目的不是为了解决跨域问题,而是在 HTML 中的 Javascript 调用出现的历史遗留问题
    1
    <script src=http://127.0.0.1/func.js?call=callfunc></script>
    这样形式的 src 远程调用,会自动绕过同源策略的限制,直接访问远程的 func.js 文件中的 callfunc 函数,并供 JS 在后续解析为 JSON 格式进行返回

而之所以叫 JSON Padding,是因为例如如下的简单实现,访问完远端 JS 文件中的 callfun 函数后(或称之为 API 后),远程的内容返回到该 HTML 文件的格式为使用 JSON 的数据封装(例如这种格式:callback({"name":"hax","gender":"Male"})

1
2
3
4
5
6
7
8
9
10
11
<html> 
<body> 
<div> 
receive <span id="qwerty"> </span> 
</div> 
</body> 
<script> function callfun(data) {document.getElementById('qwerty').innerHTML = data; } 
</script> 
<script src="http://127.0.0.1:10010/js?call=callfun">
</script>
</html>

CORS 跨域

CORS 是服务端的跨域设置,因为同源策略的原因,浏览器会限制跨域的 HTTP 请求,当跨域访问发起时,浏览器会使用 OPTIONS 方法发起一个预检请求(preflight request) ,待服务器确认可以访问后,再发送实际跨域请求。

跨域请求可能会用到如下 HEADER 头:

  • origin 预检请求(或实际请求)的原站名称
  • Access-Control-Request-Method 告诉服务器跨域请求会用到的方法
  • Access-Control-Request-Headers 告诉服务器会带的 HEADER 头

而如果服务器同意跨域,则会向客户端发起如下跨域响应

  • Access-Control-Allow-Origin 用于响应预检请求,服务器允许跨域的 URI
  • Access-Control-Allow-Methods 用于响应预检请求,实际请求的允许的 HTTP 方法
  • Access-Control-Allow-Headers 用于响应预检请求,指明实际请求允许携带的 HEADER
  • Access-Control-Expose-Headers 服务端自定义的 HEADER 只有在这里设置,客户端才能正常访问
  • Access-Control-Max-Age 预检请求的缓存时间
  • Access-Control-Allow-Credentials 如果请求中有 credentials=true 而服务端的这个 HERDER 却没有设置为 true 的时候,浏览器是不会把服务器返回的数据发回给请求者

关于 JSONP 及 CORS 绕过同源策略的原理解释

https://resek4.github.io/2022/10/03/JSONP跨域/

Author

Resek4

Posted on

2022-10-03

Updated on

2023-01-27

Licensed under

Comments