前端
const funJsonp = (params) => { //将参数转为序列化字符串 let temp = '' for (let i in params) { temp += i + '=' + params[i] + '&' } return temp}const defaultConfig = { callbackName: "jsonpCallback"}jsonp跨域const jsonp = (url, params, options = defaultConfig) => { // 返回一个可以链式调用的promise对象 return new Promise((resolve, reject) => { //将前端传递querystring查询字符串的参数,拼接到地址栏 url = url.indexOf("?") > -1 ? url + funJsonp(params) : url + '?' + funJsonp(params) url += `callback=${options.callbackName}` //动态创建script标记 const script = document.createElement("script") //设置接口的请求地址 script.setAttribute('src', url) //设置请求jsonp接口的回调函数 window[options.callbackName]=result=>{ //请求jsonp接口成功后,删除该函数 - 不污染window delete window[options.callbackName]; //从页面中删除请求接口动态创建的script标记 document.body.removeChild(script) if(result){ resolve(result) }else{ reject('服务器没有返回信息') } } //动态创建script标记,错误的监听 script.addEventListener('error', () => { delete window['jsonpCallback']; document.body.removeChild(script); reject('服务器加载失败!'); }); document.body.append(script) })}//////ajax 跨域const request=(url,params,type='GET')=>{ return new Promise((resolve,reject)=>{ const xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft','XMLHTTP') if(type==='Get'&¶ms){ url = url.indexOf("?") > -1 ? url + funJsonp(params) : url + '?' + funJsonp(params) xhr.open(type,url) xhr.send(null) }else if(type==='POST'){ xhr.open(type,url) xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded') xhr.send(funJsonp(params)) } xhr.onreadystatechange=()=>{ if(xhr.readyState===4){ if(xhr.status===200){ resolve(JSON.parse(xhr.responseText)) }else{ reject(new Error('request failed!')) } } } })}
<script src="./index.js"> </script> <script> request("http://localhost:3000/api",{username:'zhangsan',password:123},'Get').then(res=>{ console.log(res) }) request("http://localhost:3000/apiPost",{username:'zhangsan',password:13},'POST').then(res=>{ console.log(res) }) fetch("http://localhost:3000/api").then(res=>{ return res.json() }).then(res=>{ console.log(res) }) jsonp("http://localhost:3000/api",{username:111,password:222}).then(res=>{ console.log(res) }).catch(err=>{}) </script>
后台
module.exports.formatJsonp=(callbackName,params)=>{ return callbackName+'('+JSON.stringify(params)+')'}
app.get("/api",(req,res)=>{ let {query}=url.parse(req.url,true) let {callback}=query console.log(query) const {formatJsonp}=require("./config") if(callback){ res.writeHead(200,{'Content-Type':'text/javascript'}) const result={code:1,type:"jsonp"} const data=formatJsonp(callback,result) res.end(data) }else{ res.writeHead(200,{'Access-Control-Allow-Origin':"*"}) res.end(JSON.stringify({code:1,type:"json"})) }})app.post("/apiPost",(req,res)=>{ let data=req.body res.writeHead(200,{'Access-Control-Allow-Origin':'*'}) res.end(JSON.stringify({code:1,methods:'post',type:"json",data}))})