一、什么是跨域问题
在介绍如何解决跨域问题之前,我们需要明确什么是跨域问题。简单来说,当一个网页从一个域名(网址)的文档或脚本向另一个域名的资源请求时,就会出现跨域问题。这是因为浏览器出于安全方面的考虑,会限制脚本内发起跨域的http请求。而跨域的请求方法包括Ajax、WebSocket、PostMessage等。
一般而言,若两个域名不同,则被认为是跨域请求,如从 http://www.domain1.com/index.html 调用 http://www.domain2.com/index.php 。
跨域问题造成了很多方面的不便,比如网页不能正常获取跨域的资源,也不能与其他域名下的网页进行数据交互等。
二、跨域解决方案
1、JSONP
JSONP是一种解决跨域的常用方式。它是利用了script标签的跨域性质来实现的。当需要跨域请求时,对方网站在服务端将数据封装成一个函数,然后把这个函数名通过url传递给调用方,在调用方的script标签内以src引用方式调用对方的接口地址。在1.8以上的jQuery版本,跨域的jsonp请求方式可以通过设置$.ajax的dataType属性为jsonp实现。
$.ajax({ url: "http://www.domain2.com/data.php?callback=?", dataType: "jsonp", ... });
2、CORS(跨域资源共享)
CORS是W3C标准推荐的一种解决跨域问题的方式。当一个网站需要调用另一个域名下的资源时,CORS会自动向请求头添加一组信息,与对于接口的访问方进行沟通,在服务器对请求作处理之前,能够让请求发起方得到响应信息的允许信息。如果接口提供方允许该请求,则能够顺利完成请求,否则返回错误信息。需要注意的是,为了能够实现CORS请求,服务器端需要进行一定的设置。
//设置CORS header("Access-Control-Allow-Origin:*"); //允许任何来源访问 header("Access-Control-Allow-Methods:POST,GET,OPTIONS"); //允许请求的方法 header("Access-Control-Allow-Headers:Authorization,Origin, X-Requested-With, Content-Type, Accept"); //允许的请求header
3、代理转发
代理转发是一种让后端服务端请求跨域请求,在前端进行数据交互的方式。其主要思路是前端向自己的服务器发起请求,然后自己的服务器充当中间层,将请求发到要访问的地址,并将得到的内容返回给前端。这种方式需要前端和后端配合,除了解决跨域问题,也能够实现一定的安全性防护。
//前端代码 $.ajax({ type: "POST", url: "/api", data: { url: "http://www.domain2.com/server.php" }, dataType: "json", success: function (data) { console.log(data); } }); //后端代码 headers = { 'Accept': 'application/json, text/javascript, */*;', 'Accept-Encoding': 'gzip', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Content-Length': '0', 'Host': 'www.domain2.com', 'Origin': 'http://www.domain1.com', 'Referer': 'http://www.domain1.com/index.html', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3' } @app.route('/api', methods=['POST']) def api(): url = request.form.get('url') r = requests.get(url, headers=headers) return r.text
三、总结
无论是JSONP、CORS还是代理转发,每种跨域解决方案都有其各自的优劣。JSONP是一种通用的解决方案,但是只能针对get请求,存在一定的安全隐患;CORS兼容性良好,能够支持post等多种请求方式,同时也存在一定的缺点,因为需要服务器在响应头中进行设置,并不能直接控制,而且存在兼容性不好的客户端情况;代理转发是一种在后端处理的方案,可以对请求进行一定的安全防护,同时请求方式可以更加灵活。需要根据实际情况选择合适的跨域解决方案。