跨域方式
jsonp
原理
jsonP 是采用 script 的 src 访问无限制(事实上很多元素的 src 都无访问限制)。比如,当 script 访问的 url 地址为:
<script type=”text/javascript” src=”http://localhost:9999?callback=ttt“> 当服务器接收到请求时,对 query 语句进行解析(上述 query 语句为 callback=ttt),然后将 ttt 作为回调函数名称,以拼接字符串的形式,返回给浏览器,如返回:”” + “ttt (“ + data + “);” 即可。这里给出 nodejs 服务器简单设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| var http = require("http"); var fs = require("fs"); var url = require("url")
var str='';
function onRequest(request, response){ if (request.url == '/favicon.ico' ||request.url == '/' ) return; console.log("href: ",url.parse(request.url).href); var pathquery = url.parse(request.url).query; console.log("pathquery: ",pathquery) var keys = pathquery.split("&"); for (var i = 0, len=keys.length; i < len; ++i) { var temp = keys[i].split("=", 2); if (temp[0] == "callback") { var value = temp[1]; break; } } response.writeHead(200,{"Content-Type":'text/plain;charset:utf-8;'}); str = "" + value + "({price: 10,tickets: 20})"; console.log("str", str); response.end(str); } http.createServer(onRequest).listen(9999); console.log("Server has started.port on 9999\n");
|
前端页面请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 方式一,原生js: <script> function ttt(data){console.log(data.id, data.name)} </script> <script type="text/javascript" src="http://localhost:9999?callback=ttt"> 方式二,jQuery.ajax $.ajax({ type: "get", url: "http://localhost:9999", dataType: "jsonp", jsonp: "callback", jsonpCallback:"success_jsonpCallback", success: function(json){ alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。'); }, error: function(){ alert('fail'); } }); 方式三,jQuery.getJSON $.getJSON("http://localhost:9999?callback=?",function(json){
});
|
改写可跨域响应头
可以通过配置响应头实现跨域访问。
nodejs 服务器设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| var http = require("http"); var fs = require("fs"); var url = require("url")
var str='';
function onRequest(request, response){ if (request.url == '/favicon.ico' ||request.url == '/' ) return; console.log("href: ",url.parse(request.url).href); var pathquery = url.parse(request.url).query; console.log("pathquery: ",pathquery) var keys = pathquery.split("&"); for (var i = 0, len=keys.length; i < len; ++i) { var temp = keys[i].split("=", 2); if (temp[0] == "callback") { var value = temp[1]; break; } } response.writeHead(200,{"Content-Type":'text/plain;charset:utf-8','Access-Control-Allow-Origin':'http://localhost:8888','Access-Control-Allow-Methods':'PUT,POST,GET,DELETE,OPTIONS'}); str = "" + value + "({price: 10,tickets: 20})"; console.log("str", str); response.write(str+";"); response.end(str); }
http.createServer(onRequest).listen(9999); console.log("Server has started.port on 9999\n");
|
前端页面请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 方式一,原生js: $.ajax({ type: "get", url: "http://localhost:9999/", dataType: "text", data: "callback=?", success: function (data,stats) { eval("var obj =" + data.replace(/\(|\)/g,"")) console.log(obj ,stats); }, error: function (error) { console.log(error) } })
|
代理
这种方式是通过后台 (ASP、PHP、JAVA、ASP.NET) 获取其他域名下的内容,然后再把获得内容返回到前端,这样因为在同一个域名下,所以就不会出现跨域的问题。
比如在 A(www.a.com/sever.php)和 B(www.b.com/sever.php)各有一个服务器,A 的后端(www.a.com/sever.php)直接访问 B 的服务,然后把获取的响应值返回给前端。也就是 A 的服务在后台做了一个代理,前端只需要访问 A 的服务器也就相当与访问了 B 的服务器。这种代理属于后台的技术。