跨域资源共享、HTML5、jQuery/SoundManager 的奇怪问题

5

我遇到了一些与SoundCloud API和HTML5音频播放器有关的问题。

主要目标是仅使用HTML5访问所有公开可用的SoundCloud曲目。

我正在使用以下内容。

    //C# api call returning json object. Cut down version of the code as it isnt the issue.
    var method "http://api.soundcloud.com/users/{0}/favorites.json"
    var query = "?client_id=" + soundCloudClientId;

    WebClient client = new WebClient();

    return client.DownloadString(string.Format(method, artistId) + query);

我从 SoundCloud 收到了这个。为了一些相关的测试用例,又做了削减。

    {
        "Songs": 
        [
            {
                "Title": "Rio",
                "Artist": "Netsky",
                "Album": "",
                "Duration": "03:49",
                "Artwork": "https://i1.sndcdn.com/artworks-000120037955-m8t78n-t500x500.jpg",
                "StreamUrl": "https://api.soundcloud.com/tracks/210032350/stream",
                "Libary": "SoundCloud",
                "TrackId": "210032350"
            },
            {
                "Title": "FreqAsia x Nasty Wizard - Episode 01",
                "Artist": "Frequency Asia",
                "Album": "",
                "Duration": "17:50",
                "Artwork": "https://i1.sndcdn.com/artworks-000120265160-sn1a4k-t500x500.jpg",
                "StreamUrl": "https://api.soundcloud.com/tracks/210368447/stream",
                "Libary": "SoundCloud",
                "TrackId": "210368447"
            },
            {
                "Title": "Episode 023 - June 2015",
                "Artist": "Frequency Asia",
                "Album": "",
                "Duration": "44:15",
                "Artwork": "https://i1.sndcdn.com/artworks-000120689935-24wvqo-t500x500.jpg",
                "StreamUrl": "https://api.soundcloud.com/tracks/210995770/stream",
                "Libary": "SoundCloud",
                "TrackId": "210995770"
            },
            {
                "Title": "Porter Robinson - Flicker",
                "Artist": "Porter Robinson",
                "Album": "",
                "Duration": "04:39",
                "Artwork": "https://i1.sndcdn.com/artworks-000086441918-ds0915-t500x500.jpg",
                "StreamUrl": "https://api.soundcloud.com/tracks/160632928/stream",
                "Libary": "SoundCloud",
                "TrackId": "160632928"
            }
        ]
    }

这是通过Ajax在我的页面上调用的,然后使用结果在页面上渲染出一堆HTML,并绑定一个类似于以下格式的onclick函数。

    $.ajax({
        url: 'http://api.soundcloud.com/tracks/' +
             widget.get("TrackId") +
            '/streams?' +
            'client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
            '&format=json&_status_code_map[302]=200',
        dataType: 'json',
        method: "GET",
        success: function (resp) {
            $("#myAudio").attr("src", resp.http_mp3_128_url);
            $("#myAudio")[0].play();
        },
        error: function (req, status, err) {
            console.log('something went wrong', status, err);
        }
    });

当 "$(#myAudio)" 等于

    <audio id="myAudio"
       src=""
       crossorigin="anonymous"
       type="audio/mpeg"
       controls="controls"
       style="width: 100%">
        Your user agent does not support the HTML5 Audio element. Woof..
    </audio>

现在这个方法在我一半的歌曲中有效。例如:Rio - NetSky - 210032350. 但是对于 Porter Robinson - Flicker 就不行,我会遇到以下错误:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cf-media.sndcdn.com/nwtEnjuJwESE.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vbnd0RW5qdUp3RVNFLjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MzY4NDc2NDV9fX1dfQ__&Signature=JN5bWI9dRW6a-KAczl0tjeTdoKmSa5BS8eGdI3I9E~NX9N~L-E9M2LRuCSuOc0jN0vk53VodFvwtArHfnFpedZjlo-7fmRwKMcZd5LAkGvCww0OiAztuzk4GESmLF8zE8RhKOF5UlNCJNLPZYM2BLgZPuMzsfLeQSLGPDbCHkiJazXZYoPjWKS8x3AYq4IBuwrzHsDOPT3GJN0XU89ugCm8x-cEZX946udYeRNrTwVUsVpTGjXwBE8zxRIE8AZFssptJsb9rCDpq9AlSoVBmII7RqYC264R9eovCqH8OTHGrQaeCQ9sXncwckjLpa70bjouCT-1UV6ampEIs9wTaKQ__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

如果我从页面中手动删除crossorigin="anonymous"(在firbug中),那么在我更改了src之后它就会播放歌曲(正确的)。更奇怪的是,之后所有的歌曲都播放,但没有声音 >:S。

从开头删除crossorigin="anonymous"没有影响。

然而,如果我使用soundmanager方法,它似乎可以正常工作。

    SC.stream(
        "/tracks/" + widget.get("TrackId"),
        {
            useHTML5Audio: true,
            multiShotEvents: true
        },
        function (sound) {
            // This is Pure Evil
            $("#myAudio").remove();
            sound.play();
            var newPlayer = $(sound._player._html5Audio);

            newPlayer.attr('id', "myAudio");
            newPlayer.attr('type', "audio/mpeg");
            //newPlayer.attr('crossorigin', "anonymous");
            newPlayer.attr('controls', "controls");
            newPlayer.attr('style', "width: 100%");

            $('#AudioPlayerContainer').append(newPlayer);

            audio = $("#myAudio");
            audio[0].play()
        }
    );

现在回到问题的核心。
无论是html5方法还是Sound Manager方法,都会使用get请求访问以下url。
    https://cf-media.sndcdn.com/nwtEnjuJwESE.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vbnd0RW5qdUp3RVNFLjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MzY4NDc3MDl9fX1dfQ__&Signature=w9wbiSg6eYJd6LESarJl4hbTNPwEMa0tV8q1rC30E~b5UcicVw~mkR6RfMaY4pYSE489nNFjXUTTPUYJ-2T6BHnarxBl8YcRsmAsRbp3BzI6AlkutzqV4LOTma0r08WA9CpuMRJRyOnfwA271sQeYz~FkKadkTs1zKTyBbKc~WxAQvqkfwXimYpAynWmGuw7mFc-AEXEQ9wwPDBj6EJD5R1NtvBPia-jtJEdfO39I4BIwGGLeu57xIQk0GcYWhJ2rEspmfDh~Z99dKW0H5tGNC3UyVGG7cb-PKiyVOkIdKRz3paqZ6~Xu65nMC5EVD1dc7T8~sYTLsUVJkNu~aySuw__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ

Html5请求和响应头

    Host: cf-media.sndcdn.com
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
    Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5
    Accept-Language: en-US,en;q=0.5
    Origin: http://localhost:58434
    Range: bytes=0-
    Referer: http://localhost:58434/Home/Main
    Connection: keep-alive

    Accept-Ranges: bytes
    Age: 361541
    Cache-Control: max-age=252460800
    Connection: keep-alive
    Content-Length: 4465057
    Content-Range: bytes 0-4465056/4465057
    Content-Type: audio/mpeg
    Date: Thu, 09 Jul 2015 23:49:29 GMT
    Etag: "b46b442c81cdb2d253827a19291d2847"
    Last-Modified: Mon, 28 Jul 2014 11:56:24 GMT
    Server: AmazonS3
    Via: 1.1 5c5638d5b5fb0e5b90e36788792360f2.cloudfront.net (CloudFront)
    X-Amz-Cf-Id: sSqydrdg2dAC7O1q3vUszcSKjd-qPAvtMbwijwwKF_MBZ3m1yHazcA==
    X-Cache: Hit from cloudfront
    x-amz-meta-bitrate: 128
    x-amz-meta-duration: 279091
    x-amz-meta-job: nwtEnjuJwESE
    x-amz-version-id: RAqXwDop3vD2oYiHSW6PYUPyzsiuGp6H

声音管理器请求和响应头

    Host: cf-media.sndcdn.com
    User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
    Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5
    Accept-Language: en-US,en;q=0.5
    Range: bytes=0-
    Referer: http://localhost:58434/Home/Main
    Connection: keep-alive

    Accept-Ranges: bytes
    Age: 361891
    Cache-Control: max-age=252460800
    Connection: keep-alive
    Content-Length: 4465057
    Content-Range: bytes 0-4465056/4465057
    Content-Type: audio/mpeg
    Date: Thu, 09 Jul 2015 23:49:29 GMT
    Etag: "b46b442c81cdb2d253827a19291d2847"
    Last-Modified: Mon, 28 Jul 2014 11:56:24 GMT
    Server: AmazonS3
    Via: 1.1 b93cfa23ea94b492bc1948ec35e51f94.cloudfront.net (CloudFront)
    X-Amz-Cf-Id: 6KjUx89xvaKdOIvl-7IcrnNhhhnCVr2Fk_1Co-S4vt4KdytC6GfJDg==
    X-Cache: Hit from cloudfront
    x-amz-meta-bitrate: 128
    x-amz-meta-duration: 279091
    x-amz-meta-job: nwtEnjuJwESE
    x-amz-version-id: RAqXwDop3vD2oYiHSW6PYUPyzsiuGp6H

请注意:Origin: 存在于第一个请求中,但不存在于第二个请求中。我已经尝试过调整。 如何使 AJAX 请求看起来像普通请求,但是删除标头并没有成功。
因此,实际问题是如何使跨域请求像声音管理器中一样正常地运行? / 我是否遗漏了一些显而易见的问题导致此问题出现。
____ 根据评论尝试 Json P ____.
    $(document).ready(function () {
        $.ajax({
            url: 'https://cf-media.sndcdn.com/nwtEnjuJwESE.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vbnd0RW5qdUp3RVNFLjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MzY5MjUxNDl9fX1dfQ__&Signature=bd0d9hCWuXTWtdkHMVJEAYMjOyT31G1nAt9Ak3A1kKHGvNu~Ix5SqJ75OHr~R1MlfaVX3scQoqu8LSTfRdZUgOKnzRVYUpZAIKBKC-vcmdy1LNW9ounvZDdgMU6o9th4wiO2fx3HEu~UDmrypW6SgmrHWt0Smp3S8l0ypt80iKESRJHdRYI6Y~dewta~f3CGe7Om8EfzO8ZDwieGVP2sxmrYCf6rnSNKwXtcH1OXmPdkcKEJiCrxNzL8xFfNI8ONXjHm6Vj05EFc6dYOEAIxvhMR6A~uqex7tytxFocrX9C0dCL~ND-89K7oSkWgBT28WgQ8fMySx7HTTHbc3gwd4A__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ',
            dataType: 'jsonp',
            async: false,
            success: function (data) {
                $('#myAudio').attr("src","data:audio/mp4;base64,"+data);
                    $('#myAudio')[0].mAudioPlayer.load();
                    $('#myAudio')[0].mAudioPlayer.play();
            }
        });
    });

我会尝试使用JSONP。 - CapelliC
@CapelliC 除非我做错或者理解有误,否则在我开始播放之前,jsonp请求必须得到解决。我将添加一段示例代码,它似乎对我没有起作用,也许你会有更多的见解。 - Spaceman
1个回答

0

关于CORS问题,我认为你遇到了和这位先生一样的问题:SoundCloud Api redirect confusion and Audio Api Streams

至于为什么它可以在SoundManager中工作而不是你自己的请求,这就更难回答了。通过查看SoundManager源代码并根据你使用的firebug,我假设你正在使用Firefox。Firefox对mp3的支持有点不稳定,这让我想到你的Firefox可能不支持mp3,或者 SoundManager只是认为它不支持(SoundManager中的html5CanPlay逻辑并不好读..),因此降级使用Flash进行播放。如果是这样,你看到的结果可能是因为流的请求是通过ActionScript完成的,这可能会生成一个不同外观的请求。


哎呀,我不认为Firefox有问题,因为我在Chrome中也遇到了类似的问题。目前我已经完全转向使用声音管理器,现在一切都正常。我怀疑你关于Flash是流媒体工作原因的猜测是不正确的,因为我在没有Flash的环境下进行了测试,比如iPad(至少我认为它们没有Flash),结果是相同的。我会继续挖掘 :) 谢谢你的见解。 - Spaceman
啊,糟糕。没错,iPad不能运行Flash! - Oskar Eriksson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接