JavaScript - 如何为浏览器GET设置请求标头

时间:2021-03-12 16:54:29

If we do window.location = "http://MyApi.com/Pdf";, browser does a GET of the URL http://MyApi.com/Pdf. But if we want to set authentication header of the request before doing GET of the URL because the server is a REST server and it doesn't support cookies. How to do this?

如果我们执行window.location =“http://MyApi.com/Pdf”;,浏览器会执行URL http://MyApi.com/Pdf的GET。但是,如果我们想在执行URL的GET之前设置请求的身份验证标头,因为服务器是REST服务器并且它不支持cookie。这个怎么做?

In all of the cases, I'm using $.ajax to call service but this time I need to show the response in a new window. Response is a PDF file content.

在所有情况下,我使用$ .ajax来调用服务,但这次我需要在新窗口中显示响应。响应是PDF文件内容。

Thanks in advance.

提前致谢。

5 个解决方案

#1


9  

In more recent browsers, you might be able to use blobs:

在更新的浏览器中,您可以使用blob:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button onclick="tryit();">PDF</button>
<script>
    function tryit() {
        var win = window.open('_blank');
        downloadFile('/pdf', function(blob) {
            var url = URL.createObjectURL(blob);
            win.location = url;
        });
    }
    function downloadFile(url, success) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.setRequestHeader("Authorization", "Basic " + btoa("username:password"));
        xhr.responseType = "blob";
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (success) success(xhr.response);
            }
        };
        xhr.send(null);
    }

</script>
</body>
</html>

In IE, ask the user:

在IE中,询问用户:

window.navigator.msSaveOrOpenBlob(blob, 'readme.pdf');

P.S. You can test the backend in Node:

附:您可以在Node中测试后端:

router.get('/pdf', function(req, res) {
  if(req.headers.authorization !== 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=') return res.status(403).send('Not allowed');
  res.sendFile(path.join(__dirname, 'public', 'render.pdf'));
});
router.get('/', function(req, res) {
  res.render('index');
});

#2


1  

If you don't care about hiding or obfuscating the user credentials then just use plain GET authentification: use http://username:password@MyApi.com/ instead of http://MyApi.com/

如果您不关心隐藏或混淆用户凭据,那么只需使用普通的GET身份验证:使用http:// username:password@MyApi.com/而不是http://MyApi.com/

#3


1  

Does it have to be a GET?

它必须是GET吗?

The reason I am asking is that you could just have a POST form (to a target="_BLANK") that posts whatever but shows an embedded file in a new window. Of course this wouldn't solve the issue with your custom headers, but then since you can also POST using jquery.ajax - which does allow you to set your own headers - you'd have the best of both worlds.

我问的原因是你可以只有一个POST表单(到目标=“_ BLANK”)发布任何内容但在新窗口中显示嵌入文件。当然这不会解决你的自定义标题的问题,但是因为你也可以使用jquery.ajax进行POST - 这允许你设置自己的标题 - 你将拥有两全其美的优势。

Here's a jQuery plugin that creates such a form dynamically in order to download whichever file. You could use this as a reference...

这是一个jQuery插件,可以动态创建这样一个表单,以便下载任何文件。你可以用这个作为参考......

Hope this helps

希望这可以帮助

#4


1  

I think this is what you are looking for... Or correct me if i am wrong.

我想这就是你要找的......或者如果我错了,请纠正我。

https://developer.mozilla.org/en/docs/Setting_HTTP_request_headers

https://developer.mozilla.org/en/docs/Setting_HTTP_request_headers

#5


-2  

You should configure $.ajax using beforeSend. Below an example, but of course I don't know if the exact setup will work for you without any code to look at.

您应该使用beforeSend配置$ .ajax。下面是一个例子,但我当然不知道确切的设置是否适合你,没有任何代码可供查看。

$.ajax( {
    url : '/model/user.json',
    dataType : 'json',
    'beforeSend' : function(xhr) {
            var bytes = Crypto.charenc.Binary.stringToBytes(username + ":" + password);
            var base64 = Crypto.util.bytesToBase64(bytes);
            xhr.setRequestHeader("Authorization", "Basic " + base64);
    },
    error : function(xhr, ajaxOptions, thrownError) {
        reset();
        onError('Invalid username or password. Please try again.');
        $('#loginform #user_login').focus();
    },
    success : function(model) {
        cookies();
            ...
    }
});

For this to work you need crypto-js.

为此,你需要crypto-js。

#1


9  

In more recent browsers, you might be able to use blobs:

在更新的浏览器中,您可以使用blob:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button onclick="tryit();">PDF</button>
<script>
    function tryit() {
        var win = window.open('_blank');
        downloadFile('/pdf', function(blob) {
            var url = URL.createObjectURL(blob);
            win.location = url;
        });
    }
    function downloadFile(url, success) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.setRequestHeader("Authorization", "Basic " + btoa("username:password"));
        xhr.responseType = "blob";
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (success) success(xhr.response);
            }
        };
        xhr.send(null);
    }

</script>
</body>
</html>

In IE, ask the user:

在IE中,询问用户:

window.navigator.msSaveOrOpenBlob(blob, 'readme.pdf');

P.S. You can test the backend in Node:

附:您可以在Node中测试后端:

router.get('/pdf', function(req, res) {
  if(req.headers.authorization !== 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=') return res.status(403).send('Not allowed');
  res.sendFile(path.join(__dirname, 'public', 'render.pdf'));
});
router.get('/', function(req, res) {
  res.render('index');
});

#2


1  

If you don't care about hiding or obfuscating the user credentials then just use plain GET authentification: use http://username:password@MyApi.com/ instead of http://MyApi.com/

如果您不关心隐藏或混淆用户凭据,那么只需使用普通的GET身份验证:使用http:// username:password@MyApi.com/而不是http://MyApi.com/

#3


1  

Does it have to be a GET?

它必须是GET吗?

The reason I am asking is that you could just have a POST form (to a target="_BLANK") that posts whatever but shows an embedded file in a new window. Of course this wouldn't solve the issue with your custom headers, but then since you can also POST using jquery.ajax - which does allow you to set your own headers - you'd have the best of both worlds.

我问的原因是你可以只有一个POST表单(到目标=“_ BLANK”)发布任何内容但在新窗口中显示嵌入文件。当然这不会解决你的自定义标题的问题,但是因为你也可以使用jquery.ajax进行POST - 这允许你设置自己的标题 - 你将拥有两全其美的优势。

Here's a jQuery plugin that creates such a form dynamically in order to download whichever file. You could use this as a reference...

这是一个jQuery插件,可以动态创建这样一个表单,以便下载任何文件。你可以用这个作为参考......

Hope this helps

希望这可以帮助

#4


1  

I think this is what you are looking for... Or correct me if i am wrong.

我想这就是你要找的......或者如果我错了,请纠正我。

https://developer.mozilla.org/en/docs/Setting_HTTP_request_headers

https://developer.mozilla.org/en/docs/Setting_HTTP_request_headers

#5


-2  

You should configure $.ajax using beforeSend. Below an example, but of course I don't know if the exact setup will work for you without any code to look at.

您应该使用beforeSend配置$ .ajax。下面是一个例子,但我当然不知道确切的设置是否适合你,没有任何代码可供查看。

$.ajax( {
    url : '/model/user.json',
    dataType : 'json',
    'beforeSend' : function(xhr) {
            var bytes = Crypto.charenc.Binary.stringToBytes(username + ":" + password);
            var base64 = Crypto.util.bytesToBase64(bytes);
            xhr.setRequestHeader("Authorization", "Basic " + base64);
    },
    error : function(xhr, ajaxOptions, thrownError) {
        reset();
        onError('Invalid username or password. Please try again.');
        $('#loginform #user_login').focus();
    },
    success : function(model) {
        cookies();
            ...
    }
});

For this to work you need crypto-js.

为此,你需要crypto-js。