如何解决跨域问题

什么是跨域?

为什么会出现跨域问题?

遇见跨域,如何解决? 


什么是跨域?

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域.

跨域并不是请求发不出,能够正常发送请求,并且服务器收到请求后正常返回结果,但被浏览器拦截了.

为什么会出现跨域问题?

 服务器的同源策略,同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

请求url的协议,域名,端口号三个任意一个与当前页面url不同 , 请求是ajax , 请求跨域资源 会引起浏览器跨域报错.

 

遇见跨域,如何解决? 

 1.后端写代码(CORS)在响应中添加必要的响应头,响应回来之后,浏览器不报错

(1)CORS原理
CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。


(2)CORS优缺点
CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。

优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。
(3)用法

a、前端代码(需要判断浏览器是否支持情况)

function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
 
    // 此时即支持CORS的情况
    // 检查XMLHttpRequest对象是否有“withCredentials”属性
    // “withCredentials”仅存在于XMLHTTPRequest2对象里
    xhr.open(method, url, true);
 
  } else if (typeof!= "undefined") {
 
    // 否则检查是否支持XDomainRequest,IE8和IE9支持
    // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式
    xhr = new XDomainRequest();
    xhr.open(method, url);
 
  } else {
 
    // 否则,浏览器不支持CORS
    xhr = null;
 
  }
  return xhr;
}
 
var xhr = createCORSRequest('GET', url);
if (!xhr) {
  throw new Error('CORS not supported');
}

b、服务器端

response.addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 
response.addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式

2.前端用JSONP方式去发请求(jsonp不是ajax请求)

JSONP的流程(以第三方API地址为例,不必考虑后台程序)

声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。

创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=fn)。

服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{"name":"jianshu"}])。

最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。
 

<script type="text/javascript" src="http://test.com/jsonServerResponse?callback=fn"></script>
//向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
 
 
//处理服务器返回回调函数的数据
<script type="text/javascript">     
    function fn(data) {        
         alert(data.msg);     
    } 
</script> 

3.代理服务器 (适用于开发阶段)

vue.config.js配置文件中,有一项是devServer,加入以下代码

module.exports = {
  devServer: {
    // ... 省略
    // 代理配置
    proxy: {
        // 如果请求地址以/api打头,就出触发代理机制
        // http://localhost:9588/api/login -> http://线上的地址/api/login
        '/api': {
          target: 'http://线上的地址' // 我们要代理的真实接口地址
        }
      }
    }
  }
}

去掉axios基地址

({
  timeout: 5000
	// baseURL: ''
})

重启项目,验证结果

  1. 修改了配置文件,一定要重启前端项目
  2. 再次测试登陆接口,我们发现:跨域问题已经解决了
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值