一.什么是同源

所谓同源就是协议、域名、端口三者完全一样,同源策略是浏览器上为安全性设置的重要机制,Ajax可以获取同源的数据,而对于非同源的数据,Ajax默认是获取不到的。
例如,有一个url地址为http://www.example.com:80,我们用表格简单区分一下同源与非同源

url 结果 说明
https://www.example.com 非同源 协议不同,http与https
http://en.example.com 非同源 域名不同
http://www.example.com:81 非同源 端口号不同
http://www.example.com:80/index.html 同源 协议、域名、端口号完全相同

如果使用Ajax请求了非同源路径下的数据,通常会报如下错误:
request.png

二.跨域

所谓跨域就是为了访问别人服务器的数据,Ajax是访问自己服务器的数据。

三.跨域的实现

XMLHttpRequest对象默认情况下是无法获取到非同源服务器下的数据。如果要获取其数据需要通过script标签,用script标签的src属性引入一个外部文件,这个外部文件是不涉及到同源策略影响。

  1. <script type="text/javascript" src="http://www.wangle.run/test.js"></script>

跨域的本质其实就是服务器返回的一个方法调用,这个方法是我们事先定义好的,而方法中的参数就是我们想要的数据。
跨域请求大致分为四个步骤:
1.访问外部文件;2.动态创建script标签传入动态参数;3.前端界面决定方法名称;4.给window增加属性进行方法定义

四.跨域的封装

  1. //跨域封装
  2. function myDomain(obj){
  3. var defaults = {
  4. type:"get",
  5. url:"#",
  6. data:{},
  7. success:function(data){},
  8. jsonp:'',
  9. jsonpCallback:'',
  10. };
  11. for(var key in obj){
  12. defaults[key] = obj[key];
  13. }
  14. var params = "";
  15. for(var attr in defaults.data){
  16. params += attr + "=" + defaults.data[attr] + "&";
  17. }
  18. if(params){
  19. params = params.substring(0,params.length-1);
  20. defaults.url += "?" + params;
  21. }
  22. defaults.url += "&"+ defaults.jsonp + "=" + defaults.jsonpCallback;
  23. var script = document.createElement("script");
  24. script.src = defaults.url;
  25. window[defaults.jsonpCallback] = function(data){
  26. defaults.success(data);
  27. }
  28. var head = document.querySelector("head");
  29. head.appendChild(script);
  30. }
参数名 类型 说明
type String 默认为get,跨域请求的方式通常都为get
url String 服务器接口请求地址
data Object 请求的参数值,采用键值对形式。data:{ key: value }
jsonp String 调用的方法key值,可自定义。如果服务器已指定则必须传入指定方法名
jsonpCallback String 调用方法名,可自定义

实例代码:

  1. myDomain({
  2. type:"get",
  3. url:"https://www.example.com",
  4. data:{
  5. key:value,
  6. },
  7. jsonp:"callback",
  8. jsonpCallback:"text",
  9. success:function(data){
  10. console.log(data)
  11. }
  12. })