js跨域问题总结

一个域名地址的组成

  1. http://(协议)www(子域名).abc.com(主域名):8080(端口号)/somescript/jquery.js(请求资源地址)

为何会发生ajax跨域

由于浏览器同源策略的限制,不容许ajax跨域请求vue

  • 一个是浏览器的显示
  • 另外一个限制的是ajax请求

能够跨域的三个标签

  1. <img src='xxx'> :用于打点统计
  2. <link href='xxx'>:可使用CDN资源
  3. <script src='xxx'>:能够用于JSONP和CDN资源

跨域的解决办法

针对浏览器的限制

open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
复制代码

jsonp

  1. jsonp是什么
  2. 使用jsonp服务器后台须要改动吗:须要,因此跨域请求都必须通过信息提供方的容许
  3. type
  4. Content-Type

jsonp的弊端

  1. 服务器须要改动代码支持
  2. 只支持GET请求

服务器端设置http header

response.setHeader('Access-Control-Allow-Origin','http://a.com,http://b.com')
response.setHeader('Access-Control-Allow-Origin','X-Requested-With')
response.setHeader('Access-Control-Allow-Origin','PUT,POST,GET,DELETE,OPTIONS')
// 接收跨域的cookie
response.setHeader('Access-Control-Allow-Credentials','true')
复制代码

同源策略

同源的目的

  • 网站通常会把一些重要信息放在Cookie或者LocalStorage中,若是没有同源策略,这些信息能够共享,若是有人恶意窃取网站数据,这些信息就会被泄露。因此说同源策略是浏览器安全的基础。

同源策略指的是什么?

  • 同源指的是协议、域名、端口号相同
  • 通常咱们看到的网址没有显示端口号,是由于使用的默认端口80,能够省略

主域名和子域名

跨域带来问题

  • Cookie、LocalStorage没法获取
  • DOM没法获取
  • Ajax请求没法发送

跨域的解决方案

Jsonp跨域

jsonp发送的请求type是script

jsonp返回的数据不是jsonp对象而是js脚本,这个脚本是一个函数的调用,函数的名字是jsonp请求的时候写的函数,这个jsonp请求返回的值做为参数。

优势

  • 兼容性比较好,服务器改造很是小
  • 只能实现get请求,容易遭受XSS攻击

缺点

  • 服务器端须要改动,返回值再也不是JSON对象,而是JS脚本
  • 只支持GET方法
  • 发送的不是XHR请求

原生JS模拟

function jsonp({url,params,cb}) {            
  return new Promise((resolve, reject) => {                
    let script = document.createElement('script');                
    window[cb] = function (params) {                    
      resolve(params);
    }                
    params = {...params,cb};                
    let arrs = [];       
	for(let key in params){                    
		arrs.push(`${key}=${params[key]}`);                    
	}                
    script.src = `${url}?${arrs.join('&')}`;                
    document.body.appendChild(script);            
  });
};

jsonp({            
   url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',            
   params:{wd:'a'},            
   cb:'show'        
}).then(data=>{            
	console.log('jsonp跨域请求的数据为:',data);        
});
复制代码

jquery模拟

jquery原代码也是经过动态建立script标签的形式实现跨越的jquery

$.ajax({
    url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
    type: 'get',
    data: {wd:'a'},
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "show",    // 自定义回调函数名
    success:function(){
        
    },
    error:function(){
        
    }
});

复制代码

vue

this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', {
    params: {wd:'a'},
  jsonp: 'show'}).then((res) => {
    console.log(res); 
})
复制代码

手动编写一个ajax,不依赖第三方库

var xhr = new XMLHttpRequest()
xhr.open('GET','/api',false)
xhr.onreadystatechange = function (argument) {
	if(xhr.readyState === 4){
		if(xhr.status === 200){
			alert(xhr.responseTest)
		}
	}
}
xhr.send(null)
复制代码
相关文章
相关标签/搜索