———————————-(VUE肆1)————————————-

JSONP封装=>day8_9

一、JSONP

1.jsonp概念与封装注意点:

代价:需要前后端联动
精髓:自动的由插件生成方法名,并在当前的页面动态的生成函数
然后再生成的函数里头调用用户预留的回调函数
插件:自动化的去模拟基于script去实现跨域请求的过程(对用户来说是黑盒子)
参数拼接:url已经是带参的。和不带参的
id优化 额可以添加一个容器来管理id

2.自己封装的jsonp

2.1)js代码
  1. <script>
  2. /**
  3. * 1.声明一个jsonP插件对象
  4. * 作用:隔开作用域
  5. */
  6. let jsonP = {};
  7. /**
  8. *2.在插件对象中创建两个名字备用符数组
  9. */
  10. jsonP.char = {
  11. Number: '0123456789',
  12. Letter: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
  13. }
  14. /**
  15. * 通过随机数抽取备用字符数组库拼凑函数id
  16. * @param charLen
  17. * @param numLen
  18. */
  19. jsonP.newFunId = function (charLen, numLen) {
  20. let id = '';
  21. for (let i = 0; i < charLen; i++) {
  22. id += this.char.Letter.charAt(Math.random() * 52)
  23. }
  24. for (let j = 0; j < numLen; j++) {
  25. id += Math.floor(Math.random() * 10);
  26. }
  27. return id;
  28. }
  29. /**
  30. * 拼接路径
  31. * @param url
  32. * @param key
  33. * @param value
  34. */
  35. jsonP.jointUrl = function (url, key, value) {
  36. if (url && key && value) {
  37. let sign = "&"
  38. //如果是第一次
  39. if (url.indexOf('?') == -1) {
  40. sign = '?'
  41. }
  42. url += sign + key + "=" + value
  43. }
  44. return url;
  45. }
  46. /**
  47. 封装err属性方便
  48. */
  49. jsonP.err = function (msg) {
  50. console.error(msg)
  51. }
  52. /**
  53. * 发送请求函数
  54. * @param options
  55. */
  56. jsonP.req = function (options) {
  57. let jsonId={};
  58. //1.生成方法名
  59. jsonId.funId = this.newFunId(4,8);
  60. let Userurl = options.url;
  61. let Userdata = options.data;
  62. if (!options) {
  63. this.err("输入不能空")
  64. return;
  65. } else if (!Userurl) {
  66. this.err("url不能空")
  67. return;
  68. } else if (!Userdata) {
  69. //如果没有data,初始化
  70. Userdata = {};
  71. }
  72. //将函数名赋值给userdata的回调函数属性中
  73. Userdata.callback = jsonId.funId;
  74. for (let key in Userdata) {
  75. Userurl = this.jointUrl(Userurl, key, Userdata[key])
  76. }
  77. let script = document.createElement('script');
  78. script.setAttribute("id" , jsonId.funId);
  79. script.setAttribute("src" , Userurl);
  80. //动态生成函数
  81. let callback=function (result) {
  82. console.log("xxxxxxx")
  83. //业务逻辑回调
  84. if (options.callback){
  85. try {
  86. options.callback(result)
  87. }catch (e) {
  88. this.err(e.message)
  89. }
  90. }
  91. //善后
  92. let tmp=document.getElementById(jsonId.funId)
  93. tmp.parentNode.removeChild(tmp);
  94. eval(jsonId.funId+'=null')
  95. }
  96. eval("window."+jsonId.funId+"=function(result){ callback(result) }")
  97. document.head.appendChild(script)
  98. }
  99. //测试调用函数
  100. let test=function () {
  101. jsonP.req({
  102. url:"http://localhost:3000/jsonpx",
  103. data:{
  104. a:"111"
  105. },
  106. callback:function (result) {
  107. alert("成功"+result)
  108. }
  109. })
  110. }
  111. </script>

2.2)服务端测试代码
  1. router.get('/jsonpx', async function (req, resp, next) {
  2. let callback=req.query.callback;
  3. let data=req.query.a;
  4. if (!data){
  5. resp.send(`${callback}('洪吉林:我是服务端代码')`)
  6. }
  7. resp.send(`${callback}('洪吉林:我是服务端代码`+data+`')`)
  8. })