AJAX 请求跨域请求被阻止错误

Posted

技术标签:

【中文标题】AJAX 请求跨域请求被阻止错误【英文标题】:AJAX request Cross-Origin Request Blocked error 【发布时间】:2015-06-08 08:03:55 【问题描述】:

我有两个项目;第一个是asp.net web项目,第二个是嵌入式http服务器库项目。

Embedded http server project 取自:embedded http server project

我想将用户本地的视频文件保存到用户的共享存储中。我正在使用 ajax 请求从浏览器获取和发送文件。嵌入式 http 服务器应该获取字节数组并将视频保存在客户端的共享存储中。我有一个问题,我花了几天时间解决但还没有找到解决方案。

在 Chrome 中,它停留在 stream.CopyTo(streamReader);

在 Firefox 和 IE 中,它会给出“Cross-Origin Request Blocked”错误,但 Firefox 会保存文件,即使它给出了错误。

这里是ajax请求代码:

$(document).ready(function () 

      function hashFile(file, chunkSize, callback) 
        var size = file.size;
        var offset = 0;
        var chunk = file.slice(offset, offset + chunkSize);

        SendChunk(chunk,0);

        var hashChunk = function () 
            var reader = new FileReader();
            reader.onload = function (e) 

                offset += chunkSize;

                if (offset < size) 
                    chunk = file.slice(offset, offset + chunkSize);

                    SendChunk(chunk,0);
                 
                else if (offset > size)
                    offset -= chunkSize;
                    var newchunkSize = size - offset;

                    chunk = file.slice(offset, offset + newchunkSize);

                    SendChunk(chunk,1);
                
            ;

            reader.readAsArrayBuffer(chunk);
        ;

        function SendChunk(chunk,end)

            if(end>0)
            
                 var ajaxRequest = $.ajax(
                    type: "POST",
                    url: "http://clientip:8080/savefileend",
                    contentType: false,
                    processData: false,
                    data: chunk
                );
            
            else
                var ajaxRequest = $.ajax(
                    type: "POST",
                    url: "http://clientip:8080/savefile",
                    contentType: false,
                    processData: false,
                    data: chunk
                );

                ajaxRequest.done(function (e) 
                    hashChunk();

                );
                ajaxRequest.error(function (xhr) 
                    console.log(e);
                    hashChunk();
                );
            
        
    

    function fileInputHandler(evt) 
        var files = evt.target.files;
        var chunkSize = 10485760; // bytes
        var start = window.performance ? performance.now() : Date.now(); // DEBUG
        var onHashFile = function (digest) 
            var end = window.performance ? performance.now() : Date.now(); // DEBUG
            console.log(this.name, digest, (end - start) + 'ms'); // DEBUG
        ;
        for (var i = 0, len = files.length; i < len; i++) 
            hashFile(files[i], chunkSize, onHashFile);
        
    

    document.getElementById('file1')
  .addEventListener('change', fileInputHandler, false);
);

这是获取请求的嵌入式服务器代码:

var stream = request.GetRequestStream();

                using (var streamReader = new MemoryStream())
                
                    stream.CopyTo(streamReader);
                    videoTemp = streamReader.ToArray();
                

                using (var fileStream = new FileStream(path, FileMode.Append))
                
                    fileStream.Write(videoTemp, 0, videoTemp.Length);
                

顺便说一句:

对于 IE:如果我从设置安全性中启用了“跨域访问数据源”,那么它在 IE 中可以正常工作。

对于 Chrome:如果我使用 --disable-web-security parameter 启动 chrome,它在 Chrome 中可以正常工作。但我已经从代码中找到了解决方案。

【问题讨论】:

您是否仅在 firefox 上收到此错误? .. 它是否适用于其他浏览器 chrome 是我必须弄清楚的另一个问题,光标停在 stream.CopyTo(streamReader);并且一旦我关闭浏览器它就不会继续,它会以 0 字节继续并给出连接错误.. IE 给出与“在 Access-Control-Allow-Origin 标头中找不到 Origin videovault 相同的错误。XMLHttpRequest:网络错误 0x80070005,访问被拒绝。”但 IE 将视频保存为 chrome。 包含此脚本的文件应该在您发送视频文件的同一台服务器上。这是您收到阻止错误的方式。如果它们已经在同一台服务器上,请更改您的 ajax url从http://clientip:8080/savefile/savefile 它们不在同一台服务器上,web 项目将在 web 服务器上(在这种情况下是在虚拟 pc 上),任何客户端都将拥有自己的嵌入式 http 服务器来处理客户端响应,我知道听起来很奇怪,但我会通过网络项目将用户桌面上的视频文件保存到共享存储中。我正在从客户端的浏览器发送 ajax 请求,嵌入式 http 服务器将处理该请求。 如果我将这个添加到 ajax 请求中; beforeSend: function (request) request.setRequestHeader("Access-Control-Allow-Origin", "*"); request.setRequestHeader("Access-Control-Allow-Headers", "Content-Type"); 然后调试在stream.CopyTo(streamReader); 停止,如果我关闭网页它会继续,但这次流式阅读器是空的,如果我停止 http 服务器,那么它会给我同样的错误......! @sMr 【参考方案1】:

这个问题可能出在客户端浏览器上。例如,默认情况下,谷歌浏览器被阻止跨域。要允许它,您可以使用插件:https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi

【讨论】:

我已经为 chrome 添加并启用了该插件,但与我在上面的帖子中评论的一样。【参考方案2】:

如果有人需要,我已经找到了解决方案; 我已经使用http://nancyfx.org/ Nancy.Hosting.Self 库用于嵌入式 http 服务器,在这里我可以将“Access-Control-Allow-Origin”添加到 response.Headers 以便我可以正确地传输文件。

【讨论】:

以上是关于AJAX 请求跨域请求被阻止错误的主要内容,如果未能解决你的问题,请参考以下文章

jQuery ajax 请求因为跨域而被阻止

Ajax 跨域请求被阻止:同源策略不允许读取远程资源

Ajax:跨域请求被阻止:同源策略不允许读取远程资源

Ajax - 跨域请求被阻止 - 'Access-Control-Allow-Origin' 缺失 - Spring Boot

跨域请求被阻止:同源策略不允许读取某个 URI 处的远程资源

Autodesk Forge 跨域请求被阻止错误