100steps / Blogs

:green_apple: 创新,只为与你分享。
134 stars 32 forks source link

跨域请求 #64

Open linJ-000 opened 7 years ago

linJ-000 commented 7 years ago

挺常见的一个问题。Ajax技术实现了向服务器额外请求数据而不用重新加载整个页面,Ajax技术的核心是XMLHttpRequest对象。由于浏览器的同源策略,XHR对象只能访问与包含它的页面位于同一域中的资源。也就是说XHR对象不能跨域请求资源。只要协议,主机名,端口号中有一个不一样就会形成跨域。举个栗子,后端的同学写好了接口并放在服务器上,前端的同学在本地测试的时候直接调用这个接口,这样就会形成跨域。跨域的时候浏览器控制台会有报错,类似XMLHttpRequest cannot load...之类。 现在解决跨域问题有很多种方法:

一、CORS(Cross-origin resource sharing)跨域资源共享

这是一个官方办法。实际上服务器收到了跨域的请求并响应,但是这个响应被浏览器拦截了。不追究原理的话,在后台返回的响应头部添加res.header("Access-Control-Allow-Origin", "*");就可以解决问题。这里我只讲了不带凭证的简单请求的情况(HEAD,GET,POST)的情况。如果要用复杂请求(PUT,OPTIONS等),还要设置其他响应头部。 如果这个跨域请求带凭证(cookie、HTTP认证及客户端SSL证明等),服务器需要设置Access-Control-Allow-Credentials: true前端需要在Ajax中将withCredentials设置为true var xhr = new XMLHttpRequest(); xhr.withCredentials = true; 现代浏览器都支持CORS,感觉这个应该是最简单的办法。

二、JSONP(JSON with Padding)

在CORS出现前,各路大神就发明了各种方法解决跨域问题,JSONP应该是最流行的一种。 json大家都知道是一种格式,jsonp呢,可以理解为聪明的程序猿发明出来用来绕过同源策略,实现跨域请求的方法。 简单地讲一下原理,程序员发现那些带src属性的标签是不受同源策略影响的,比如< img>(这个标签居然不能显示,所以前面多打了一个空格), Githubissues.

  • Githubissues is a development platform for aggregating issues.