导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

定义

Untitled

⭐️ 如何绕过同源策略

Untitled

script 标签不关心引用的文件类型

script 标签就是用来解析脚本的,它只解析文件里的文本,是脚本就能解析

// js/index.txt
var a = 1;
<script src="js/index.txt"></script>
<script>
  console.log(a); // 虽然引用的是 txt 文件,但仍然能打印1
</script>

jsonp 方案

服务端的 jsonp.js

Untitled

Untitled

服务端的 jsonp.php

script 脚本不看 jsonp.php 这个文件后缀名,只看这个引用脚本最终返回回来的是什么

Untitled

Untitled

客户端动态创建 script 标签

Untitled

jQuery 的 jsonp 请求

Untitled

如果不设置 jsonpCallback: 'test' ,返回的数据就是下面类似请求:

Untitled

也就是jQuery内部给你每次ajax请求随机生成了一个callback函数名,后端看到 cb 后,就直接取用cb等于后边的这个随机函数名,调用即可。

百度搜索用的 jsonp 方案

Untitled

继续封装 $ajax 异步请求函数

核心代码

var opt = opt || {},
    type = (opt.type || 'GET').toUpperCase(),
    async = "" + opt.async === 'false' ? false : true,
    dataType = opt.dataType || 'JSON',
    jsonp = opt.jsonp || 'cb',
    jsonpCallback = opt.jsonpCallback || 'jQuery' + randomNum() + "_" + new Date().getTime(),
    url = opt.url,
    data = opt.data || null,
    timeout = opt.timeout || 30000,
    error = opt.error || function() {},
    success = opt.success || function() {},
    complete = opt.complete || function() {},
    t = null;

if (dataType.toUpperCase() === 'JSONP' && type !== 'GET') {
  throw new Error('如果dateType为JSONP,请你将type设置为GET');
}

if (dataType === 'JSONP') {
  var oScript = document.createElement('script');
  oScript.src = url.indexOf('?') === -1
    ? url + '?' + jsonp + '=' + jsonpCallback
  : url + '&' + jsonp + '=' + jsonpCallback;

  document.body.appendChild(oScript);
  document.body.removeChild(oScript);

  window[jsonpCallback] = function(data) {
    success(data);
  }

  return;
}

function randomNum() {
	var num = '';
  for (var i = 0; i < 20; i++) {
    num += Math.floor(Math.random() * 10);
  }
  return num;
}

免费 jsonp 资源

Untitled

Untitled