jsonp这个概念,做前端的人几乎都听过,但真正搞清楚底层怎么跑的、自己能不能手写一个的,其实没那么多。说白了,jsonp就是利用浏览器允许跨域加载script脚本这个特性,把API返回的数据包在一个回调函数里,浏览器执行这个脚本就"跨域"了。今天把原理拆开讲,再手写一个最简实现。
jsonp怎么实现跨域
浏览器有个很老的同源策略限制:XHR不能跨域发请求。但cript>标签例外,它的src可以指向任何域名,浏览器照样加载执行。jsonp就是钻了这个空子。前端往跨域URL发请求时,告诉服务端"把数据包在我叫foo的函数里",服务端返回foo({name:"Agnes",age:25})这样的脚本片段,浏览器加载执行,数据就到手了。整个过程没有CORS头,纯粹是script标签在干活,Content-Type是application/javascript。
实际动手时,前端动态创建script节点挂到body上,把回调函数名暴露在window上,URL里带上callback=foo参数。服务端识别到callback后把JSON序列化成函数调用形式返回。前端在回调里拿到数据后,立刻清掉临时script节点和window上的函数,一次调用结束。
手写jsonp要注意什么
最核心的细节有三个。回调函数名必须随机生成,用时间戳拼,别写死,防止跟页面已有函数重名或者多次并发调用互相覆盖。第二个是超时定时器,script标签加载失败在很多浏览器里不触发error事件,得手动设个5秒timeout,到期没回调就清现场、抛错误。第三个是清理,回调执行完立刻delete window[fnName],同时移除DOM里的script节点,不然内存会慢慢涨。
写一个极简版大概三十来行:生成随机函数名挂window,拼URL,new script塞进body,回调里resolve Promise,timeout里reject。现在新项目里jsonp用得少了,CORS加fetch基本覆盖绝大多数场景,但老接口、政务系统、部分第三方SDK还在用这套。面试被问到跨域,手写一个能拿分。
理解了script标签跨域加载这个底层逻辑,后面碰CORS、fetch、WebSocket这些新方案,对比着看就都通了。原理不复杂,难在随机名、超时、并发安全这些细节上。










