【问题标题】:Ajax request: Refused to set unsafe headerAjax 请求:拒绝设置不安全的标头
【发布时间】:2016-01-13 15:07:45
【问题描述】:

我正在尝试使用 Google Text-To-Speech 播放音频。因此,我需要在正确设置 RefererUser-Agent 的情况下向他们的端点发布请求。此调用应返回一个我可以播放的 MP3。

但是,我收到 Refused to set unsafe header 错误。这是我的代码。我该怎么做?

          $.ajax({
            url: 'http://translate.google.com/translate_tts?ie=UTF-8&q=Hello&tl=en&client=t',
            beforeSend: function(xhr) {
                 xhr.setRequestHeader("Referer", "http://translate.google.com/");
                 xhr.setRequestHeader("User-Agent", "stagefright/1.2 (Linux;Android 5.0)");
            }, success: function(data){
                el.mp3 = new Audio(data);
                el.mp3.play();
            }
          });

【问题讨论】:

  • 不管你设置什么标题,谷歌翻译端点不支持CORS
  • 从 cURL 可以正常工作...
  • @Arturo — 对于 cURL,您是自己发出请求,而不是要求访问者的浏览器代表您在后台悄悄地执行此操作。当您试图让其他人的浏览器执行操作时,会有很多额外的安全限制。

标签: javascript ajax request user-agent http-referer


【解决方案1】:

你不能。这是不可能的。

如果您尝试设置Referer 标头,specification 要求浏览器中止setRequestHeader 方法(以前User-Agent 也被禁止,但现在已经改变)..

如果您需要手动设置Referer,那么您需要从您的服务器而不是访问者的浏览器发出请求。

(也就是说,如果您需要对用户代理或引用者进行欺骗,那么您可能正在尝试以所有者不想要的方式使用该服务,因此您应该尊重这一点并停止尝试)。

请注意,虽然 jQuery 封装了 XHR,但同样的规则适用于 fetch

【讨论】:

    【解决方案2】:

    空的 OriginReferer 标头与来自 <iframe>GET XMLHttpRequest

    其实,这可能的;至少对于普通网页。 诀窍在于injectingXMLHttpRequest 函数变成一个空的<iframe>。 空的<iframe> happens to be about://blank 的来源,导致空的OriginReferer HTTP 标头。

    HTML:

    <iframe id="iframe"></iframe>
    

    JavaScript:

    const iframe    = document.getElementById('iframe');
    const iframeWin = iframe.contentWindow || iframe;
    const iframeDoc = iframe.contentDocument || iframeWin.document;
    
    let script = iframeDoc.createElement('SCRIPT');
    
    script.append(`function sendWithoutOrigin(url) {
        var request = new XMLHttpRequest();
    
        request.open('GET', url);
    
        request.onreadystatechange = function() {
            if(request.readyState === XMLHttpRequest.DONE) {
                if(request.status === 200) {
                    console.log('GET succeeded.');
                }
                else {
                    console.warn('GET failed.');
                }
            }
        }
        request.send();
    }`);
    
    iframeDoc.documentElement.appendChild(script);
    

    JavaScript 调用:

    var url  = 'https://api.serivce.net/';
        url += '?api_key=' + api_write_key;
        url += '&field1=' + value;
    
    iframeWin.sendWithoutOrigin(url);
    

    在使用第三方 API 服务时,可以发送空的 OriginReferer HTTP 标头对保护隐私很重要。在某些情况下,原始域名可能会泄露敏感的个人信息;例如,暗示某种医疗状况。想想https://hypochondriasis-support.org :-D

    通过检查 .har 文件中的请求来测试代码,该文件保存自 Vivaldi 中 F12 开发人员视图中的 Network 选项卡。

    没有尝试设置User-Agent 标头。如果这也有效,请发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 2014-07-07
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2018-01-17
      相关资源
      最近更新 更多