在另一台服务器上通过XMLHttpRequest发送文件

时间:2013-02-12 11:44:32

标签: javascript xmlhttprequest

我喜欢尝试通过javascript XMLHttpRequest发送带有附加文件的POST表单。

这是我的代码:

window.addEventListener('load', function() {
    var button = document.getElementById('start_file_upload_button');
    button.addEventListener('click', function()
        {
        document.getElementById("file_upload_button_button").style.display = "none";
        var mfs         = document.getElementsByName('MAX_FILE_SIZE')[0].value,
            to_up_files = document.getElementById('to_upload_files_field'),
            status      = document.getElementById('file_upload_status_text'),
            errorlog    = document.getElementById('file_upload_error_log'),
            progress    = document.getElementById('file_upload_progress_bar');
        for(var i = 0; i < document.getElementById('to_upload_files_field').files.length; ++i) {
            document.getElementById('remove_link_' + i).style.display = "none"; }
        for(var i = 0; i < <?php echo $__CONFIG['UPLOAD']['MAX_FILE_AT_ONCE']; ?>; ++i)
            {
            if(typeof(document.getElementById('to_upload_files_field').files[i]) == "undefined") break;
            var upload   = document.getElementById('to_upload_files_field').files[i],
                filename = upload.name,
                filesize = upload.size,
                mfs      = mfs; alert(filename);
            if(filesize > <?php echo $USER_DATA['UPLOAD_MAX_FILE_SIZE']; ?>)
                {
                var errorelem  = document.createElement('span');
                var errorbreak = document.createElement('br');
                errorelem.appendChild(document.createTextNode('Die Datei "' + filename + '" ist zu Groß'));
                errorelem.appendChild(errorbreak);
                errorlog.appendChild(errorelem);
                break;
                }
            if(<?php echo $USER_DATA['SPACE_MAX']; ?> < (filesize + <?php echo $USER_DATA['SPACE_USED']; ?>))
                {
                var errorelem  = document.createElement('span');
                var errorbreak = document.createElement('br');
                errorelem.appendChild(document.createTextNode('Die Datei "' + filename + '" past nicht mehr auf die Platte'));
                errorelem.appendChild(errorbreak);
                errorlog.appendChild(errorelem);
                break;
                }
            if(filesize > (<?php echo $USER_DATA['TRAFFIC_PER_DAY'] - $USER_DATA['TRAFFIC_USED']; ?>) && (<?php echo $USER_DATA['TRAFFIC_PER_DAY'] - $USER_DATA['TRAFFIC_USED']; ?>) != 0)
                { // SPERRE EINBAUEN DAS ES NUR GEPRÜFT WIRD WENN DIE TRAFFIC ÜBERWACHUNG AKTIVIERT IST
                var errorelem  = document.createElement('span');
                var errorbreak = document.createElement('br');
                errorelem.appendChild(document.createTextNode('Die Datei "' + filename + '" braucht mehr traffic als du hast'));
                errorelem.appendChild(errorbreak);
                errorlog.appendChild(errorelem);
                break;
                }
            status.innerHTML = "Lade " + filename + " hoch...";
            var request = new XMLHttpRequest();
            request.open('POST', 'http://www.domain.tld/user/upload/', true);
            request.setRequestHeader('Content-Type', 'multipart/form-data');
            request.upload.addEventListener('progress', function(evt)
                {
                var uploaded = Number((100 / evt.total) * evt.loaded).toFixed(2);
                progress.innerHTML = "Upload zu " + uploaded + "% fertig";
                if(uploaded = 100.00)
                    {
                    progress.innerHTML = "Datei wird verarbeitet... Bitte warten...";
                    }
                }, false);
            request.addEventListener('load', function(evt) {
                alert("lol2"); }, false);
            var data = new FormData();
            data.append('upload_key', '<?php echo $upload_key; ?>');
            data.append('MAX_FILE_SIZE', mfs);
            data.append('file', upload);
            request.send(data);
            request.onload = function()
                {
                if(this.status == 200)
                    {
                    alert("lol");
                    }
                else
                    {
                    alert("Some Upload Error");
                    }
                };
            }
        }, false);
    }, false);

当我将它发送到“http://www.domain.tld/user/upload/”时,脚本运行良好而没有问题 但是我想将它发送到“http://sub.somain.com/store/”,这不起作用,为什么?

控制台日志发送到“www.domain.tld”:

  

[12:21:51.085] POST http://www.domain.tld/user/upload/ [HTTP / 1.1 200   OK 5ms]

控制台日志发送到“sub.domain.tld”:

  

[12:21:17.786]选项http://sub.domain.tld/store/ [HTTP / 1.1 200 OK 7ms]

服务器运行相同的脚本,我该怎么办?

2 个答案:

答案 0 :(得分:1)

Javascript不允许您在域之间发出请求,但如果服务器发送带有白名单域名称的Access-Control-Allow-Origin标头,则可以更改此行为。

CORS

正如我所说,您可以使用特殊响应标头来允许跨域请求。此方法称为 CORS - 跨源资源共享 就像这样使用:

header("Access-Control-Allow-Origin: www.domain.tld");

不幸的是,这只是最近才引入的,并且浏览器支持很差。

CORS Browser support

JSONP

解雇跨域请求的另一种方法是JSONP。这只能应用于GET请求。因为您正在发送POST,所以我不会进一步介绍。

I帧

您可能已经忘记了使用Iframe的可能性。当然,在这种情况下,您将不会获得任何返回值,并且无法监视上载过程。但是,如果您在iframe中触发alert()功能,您仍然可以通知用户有关成功的信息。此外,您可以从iframe重新加载页面:

window.top.location = "domain.com/script.php?upload=sucessfull";

答案 1 :(得分:0)

你违反了“同源政策”。您可以返回Access-Control-Allow-Origin标头,该标头会告诉浏览器允许该请求,但browser support isn't 100%。看看the documentation for your web server or programming language

如果您需要100%的浏览器支持,那么您可能最好上传到父域的/ tmp,然后向子域发出cURL请求。