深深地掉入一个叫做同源跨域的大坑

  已经被伤害的无法自拔,不然周末也不会苦逼的在这加班,说说问题的来源。最近在研究html5.想要从喜马拉雅那边获取到他们的点播接口。就在我把sig和aceess_token算好了之后就被这个同源策略给坑的不行。

先把我的url地址放上来:

(http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&

device_id=mybeb&pack_id=com.video&access_token=e907ca4a6b36c15af6d0ad9963b29513&sig=9a22323ab2f4e87e63b395b0492ac9dd)

   然后按照平常的思路,只知道一个url地址想要取到里面的json数据当然就是js里面的ajax。
   所以代码就来了:
法1:
function loadXMLDoc()
{
   
  1. //1.创建XMLHttpRequest对象     
  2. //这是XMLHttpReuquest对象无部使用中最复杂的一步     
  3. //需要针对IE和其他类型的浏览器建立这个对象的不同方式写不同的代码
 var xmlhttp; if (window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest(); } else { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; alert(xmlhttp.responseText); } } xmlhttp.open("GET","http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&device_id=mybeb&pack_id=com.video&access_token=e907ca4a6b36c15af6d0ad9963b29513&sig=9a22323ab2f4e87e63b395b0492ac9dd",true); xmlhttp.send(); }

   然后运行之后浏览器就来了这样一个东西。好吧就是同源策略。
   然后启用firebug在网络里面查到的就是这个鬼,完全被拦截了好吗,json数据就出不来?
然后就去找同源策略的相关解决办法,看了一下大概有一下几种:
  1.把两个地址改在同一个域名下,反正域名这东西我一直不太懂,但是显然不适合我这个,我就一个html5文件,运行出来肯定是localhost啦,不知道怎么改。
  2.加一个响应头;Access-Control-Origin,这个响应头要在服务器那端加,改服务器代码肯定是不可能的,又不是我的。
  3.好像是所谓的window.postmessage()方法,没怎么看懂,不过按照案例试了一下game over。 
法2:就是用jquery然后用jsonp的方式:
$(function(){
    $.ajax({
        async: false,
        type: "GET",
        dataType: 'jsonp',
        jsonp: 'callback',
        jsonpCallback: 'callbackfunction',
        url: "http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&" +
        "device_id=mybeb&pack_id=com.video&access_token=f299e2d8e4cf8f0c43d80854d0f6e364&sig=b880936cead04e026c4ba0b0f89cb86e",
        data:"",
        timeout: 3000,
        contentType: "application/json;utf-8",
        success: function(msg) {
            console.log(msg);
        }
    });
})
倒是没有同源策略了。那么问题又来了;400错误:请求地址不存在或者包含不支持的参数  地址和参数肯定都是在的。
这样倒是有Json数据了,可是呢报101错误呀  signature check failed  签名验证失败,然后我又陷入了无限的循坏中,sig算了不下十遍,一个appkey算怕出错,又算了一个,算到自己都不知到再算什么了。
后来又想会不会是这个地址不支持用jsonp呢,毕竟不是官方发布的。
法3:这次采用了代理服务器。就是yahoo的那个;
 $(function(){
            $.getJSON("http://query.yahooapis.com/v1/public/yql", {
                q: "select * from json where url=\"http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&" +
                "device_id=myweb&access_token=af83b6fae5d7fd427d3df44dbf8ae7f8&sig=80f54d726210718c7ce6f3ad54cdb4ef\"",
                format: "json"
            }, function(data) {
                var $content = $("#content");
                if (data.query.results) {
                    var s="";
                    var json = data.query.results.json.json;
                   for(var i=0i<json.lengthi++) {
                        s+="id:"+json[i].id + "\n" + "kind:"+json[i].kind"\n" +"category_name:" +json[i].category_name + "\n" +"cover_url_small:"json[i].cover_url_small + "\n" +"cover_url_middle:"json[i].cover_url_middle +"\n"+"cover_url_large:" + json[i].cover_url_large+"<br/>";
                    }
                    $('#content').html(s);
                } else {
                    $content.text('no such code: ' + code);
                }
            });
        });
这次可以啦,只是用代理会减慢请求速率,并且还将希望寄托在他人服务器上,必须得保证他人服务器不崩溃,有一定局限性。
法4:内嵌一个script 然后通过回调函数。 
var callbackfunction = function(data) {
    console.log('我是跨域请求来的数据-->' + data.name);
};
var script = document.createElement('script'),
        body = document.getElementsByTagName('body');
script.src ='http://api.ximalaya.com/categories/list?app_key=b90545b0ff18ac24bc6c10fd7bcb9fa3&client_os_type=3&' +
        'device_id=mybeb&pack_id=com.video&access_token=e907ca4a6b36c15af6d0ad9963b29513&sig=9a22323ab2f4e87e63b395b0492ac9dd?callback=callbackfunction';
body[0].appendChild(script);
这次也解决啦;
只是,最后法1,2,3,4都没有采用,采用的是node.js啦。比上面的几种办法要好点;
这里也附上代码:
'use strict';
var http=require("http");
var request =require("request");
var server=http.createServer(function(req,res){
    if(req.url!=="/favicon.ico"){
        request.post({url: 'http://api.ximalaya.com/oauth2/secure_access_token', timeout: 3000, form: {client_id:'8a6ac9fa6af234963329f674d3513f95',device_id:'myweb',grant_type:'client_credentials',nonce:'7abe3tsfef',timestamp:'1453116822556',sig:'cab74d75d8744ad331c0283b0a18964d'}},
          function (error, response, data) {
             if (!error && response.statusCode == 200) {
                  console.log(data);
            } else {
                  console.log(data);
        }
        res.statusCode=200;
        res.sendDate=true;
        res.setHeader("Content-Type","text/plain");
        res.setHeader("Access-Control-Allow-Origin","*");
        res.write(data.toString());
        res.end();
     });
    }
});
server.listen(1053,"localhost",function(){
    console.log("开始监听...");
});







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章