如何为特定网页启用UniversalXPConnect?

时间:2010-02-26 00:33:43

标签: ajax

我需要测试各种网络服务,这些网站服务是将上传文件作为正文内容的帖子。为此,我想使用ajax调用进行快速测试。我找到了以下页面,它描述了如何执行此操作:     http://www.captain.at/ajax-file-upload.php 但是,它要求页面在firefox中具有“UniversalXPConnect”权限。

如何启用该权限?我尝试编辑prefs.js并添加:

user_pref("capability.principal.foo.id", "http://localhost:8080/access/index.html");
user_pref("capability.principal.foo.granted", "UniversalXPConnect");

应该可以访问页面http://localhost:8080/access/index.html。但是,它似乎不起作用。

2 个答案:

答案 0 :(得分:1)

如果用户指定了该文件,则不需要UniversalXPConnect。 HTML5文件API就足够了:

<html>
<head>
<title>HTML5 File API</title>
</head>
<script type="text/javascript">
// <!--
// See: http://dev.w3.org/2006/webapi/FileAPI/

function upload (input) {
    for (var i = 0; i < input.files.length; ++ i) {
        // makes multiple uploads
        uploadFile(input.files[i]);
    }
}

function uploadFile (file) {
    var reader = new FileReader();
    reader.onprogress = function (event) {
        var percent = 100 * event.loaded / event.total;
        // TODO: display progress
    };

    reader.onerror = function (event) {
        // display error
        alert(errorMessage(reader.error)+': '+file.name);
    };

    reader.onload = function (event) {
        if (reader.error) {
            // display error
            alert(errorMessage(reader.error)+': '+file.name);
        }
        else {
            // You could also use reader.readAsBinaryString(file)
            // and the mozilla specific function call btoa(reader.result).
            // For more mozilla specific stuff (e.g. sending data as binary)
            // see: https://developer.mozilla.org/en/using_xmlhttprequest
            var data = reader.result.substring(reader.result.search(',')+1);
            var text = document.getElementById('text').value;
            var request = new XMLHttpRequest();
            var boundaryString = guid();
            var boundary = '--' + boundaryString;

            while (text.search(boundary) != -1) {
                boundaryString = guid();
                boundary = '--' + boundaryString;
            }

            var requestbody = boundary + '\n' +
                'Content-Disposition: form-data; name="mytext"\n' +
                '\n' +
                text +
                '\n' +
                boundary + '\n' +
                'Content-Disposition: form-data; name="myfile"; filename="' +
                file.name.replace(/"/g, '') + '"\n' +
                'Content-Type: application/octet-stream\n' +
                'Content-Transfer-Encoding: base64\n' +
                '\n' +
                data + '\n' +
                boundary;

            request.onreadystatechange = function () {
                if (request.readyState == 4) {
                    if (request.status == 200) {
                        alert('Result: ' + request.responseText);
                    }
                    else {
                        alert(
                            'Error "' + request.statusText + '" occured while uploading: ' +
                            file.name);
                    }
                }
            };

            /* a non-standard variant (still supported by many browsers) would be:
            request.onuploadprogress = function () {
                // possibly only mozilla, but awesome! upload progress!
                var percent = 100 * event.loaded / event.total;
                // TODO: display progress
            };

            request.onload = function () {
                if (request.status == 200) {
                    alert('Result: ' + request.responseText);
                }
                else {
                    alert(
                        'Error "' + request.statusText + '" occured while uploading: ' +
                        file.name);
                }
            };

            request.onerror = function () {
                alert(
                    'There was a problem with the request when uploading file: ' +
                    file.name);
            };
            */

            request.open('POST', 'post.php', true);
            request.setRequestHeader('Content-type', 'multipart/form-data; boundary="' +
                boundaryString + '"');
            request.setRequestHeader('Connection', 'close');
            request.setRequestHeader('Content-Length', requestbody.length);
            request.send(requestbody);

        }
    };

    reader.readAsDataURL(file);

    // there would also be:
    // reader.readAsBinaryString(file);
    // reader.readAsText(file, 'UTF-8');
    // reader.readAsArrayBuffer(file);
}

function errorMessage (error) {
    switch (error.code) {
        case FileError.ABORT_ERR:
            return 'Aborted';

        case FileError.ENCODING_ERR:
            return 'Encoding Error';

        case FileError.NOT_FOUND_ERR:
            return 'File not found';

        case FileError.NOT_READABLE_ERR:
            return 'File is not readable';

        case FileError.NO_MODIFICATION_ALLOWED_ERR:
            return 'File is not writeable';

        case FileError.SECURITY_ERR:
            return 'Security Error';

        default:
            return 'Unknown error code: ' + error.code;
    }
}

// from: https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
function S4() {
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}

function guid() {
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}

// -->
</script>
<body>
<input type="text" id="text" value="My text.."/>
<input type="file" onchange="upload(this);"/>
</body>
</html>

不过,我建议使用iframe,因为所有浏览器都支持它: Is it possible to use Ajax to do file upload?

答案 1 :(得分:1)

改进panzi的答案,您可以使用FormData对象以非常简单的方式使用Ajax发送文件:

<html>
<head>
<title>HTML5 File API</title>
</head>
<script type="text/javascript">
// <!--
// See: https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects
function upload() {
    var uploadRequest = new XMLHttpRequest,
        uploadForm = document.getElementById('file_upload');

    function transferProgress(progressEvent) {
    /*Executes For each update of the progress of the Ajax transfer.*/
        // show progress bar or something....
    }
    function transferComplete() {
    /*Executes when the transfer is complete.*/
        //Do something like show a nice message...
    }
    function transferFailed() {
    /*Executes when the transfer fails.*/
        alert('Upload failed!');
    }
    function transferCanceled() {
    /*Executes when the transfer is canceled.*/
        alert('Upload canceled!');
    }

    uploadRequest.upload.addEventListener('progress', transferProgress, false);
    //uploadRequest.upload.addEventListener('load', transferComplete, false); // transfer complete, but this doesn't mean a response from the server has been received.
    uploadRequest.addEventListener('load', transferComplete, false); // ajax request complete, response from the server has been received and all has been processed.
    uploadRequest.upload.addEventListener('error', transferFailed, false);
    uploadRequest.upload.addEventListener('abort', transferCanceled, false);

    uploadRequest.open('POST', action, true);
    uploadRequest.send(new FormData(uploadForm));
}
// -->
</script>
<body>
<form id="file_upload" enctype="multipart/form-data">
    <input type="text" id="text" value="blah blah blah"/>
    <input type="file" onchange="upload();"/>
</form>
</body>
</html>