Hide referrer header in API request

4.7k views Asked by At

I need to make requests to Google Translate Text-To-Speech API. I have an enabled key but keep getting blocked by No Access-Control-Allow-Origin.

I've posted more about it here:

Google Translate API - No Access Control Origin with Text to Speech

The following sources, http://weston.ruter.net/2009/12/12/google-tts/ and Request to Google Text-To-Speech API say that

Google returns a 404 error if the HTTP request contains a Referer header other than an empty string.

Given a request like:

    $.get('https://translate.google.com/translate_tts?key='+myKey+'&ie=utf-8&tl=en&q=Hello+world',
        function (returned_data) {

How do I hide or remove the referrer header so I'm not blocked?

this source says to put https://href.li/... in front. So I changed it to:

$.get('https://href.li/?https://translate.google.com/translate_tts?key='+key+'&ie=utf-8&tl=zh-CN&q=你好',

And am still blocked.


Server-Side attempt: No response.

This blog provides a server-side script which sets the referrer to an empty string. He says:

This gets the information from that access point and spits it out right away. But before it requests the data using file_get_contents, the Referer header is set to an empty string.

/php/testPHP.php:

$qs = http_build_query(array("ie" => "utf-8","tl" => $_GET["tl"], "q" => $_GET["q"]));
$ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: \r\n")));
$soundfile = file_get_contents("http://translate.google.com/translate_tts?".$qs, false, $ctx);

header("Content-type: audio/mpeg");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');

echo($soundfile);

index.php (root):

<audio controls="controls" autoplay="autoplay" style="display:none;">
            <source src="/php/testPHP.php?translate_tts?tl=en&q=the%20brown%20fox%20jumped%20over%20the%20lazy%20dog." type="audio/mpeg" />
</audio>

tail -f apache error logs:

PHP Notice: Undefined index: tl in /Users/myname/Sites/app/melonJS-dev/testPHP.php on line 4, referer: http://melon.localhost/

PHP Warning: file_get_contents(https://translate.google.com/translate_tts?ie=utf-8&q=the+brown+fox+jumped+over+the+lazy+dog): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found\r\n in /Users/myname/Sites/app/melonJS-dev/testPHP.php on line 6, referer: http://melon.localhost

tail -f access log: Shows the tl param getting passed in with a 200:

GET /testPHP.php?translate_tts?tl=en&q=the%20brown%20fox%20jumped%20over%20the%20lazy%20dog HTTP/1.1" 200 -


JSONP Attempt: so I thought perhaps wrapping the return object in a <script> would solve the issue. I get no response.

    $.ajax({
        url: 'https://translate.google.com/translate_tts?key='+key+'&ie=utf-8&tl=zh-CN&q=你好',
            type: 'GET',
            dataType: 'jsonp',
            error: function(xhr, status, error) {
            alert("error");
        },
        success: function(json) {
            alert("success");
        }
        });

HTML/JS text-to-speech attempt: 404 block

js:

    <script>
        $(function() {
            $('a.say').on('click', function(e) {
                e.preventDefault();
                var text = $('input[name="text"]').val();
                text = encodeURIComponent(text);
                console.log(text);
                //var url = 'https://translate.google.com/translate_tts?&ie=utf-8&tl=zh-CN&q=' + text;
                var url = 'https://translate.google.com/translate_tts?ie=UTF-8&q=' + text + '&tl=en';
                $('audio').attr('src', url).get(0).play();
            });
        });
    </script>

html:

    <input type="text" name="text">
    <a href="#" class="say">Say it</a>

    <audio src="" class="speech" hidden></audio>

Following this tutorial: https://www.youtube.com/watch?v=DOtkNxmg9QY

2

There are 2 answers

1
Kirill Fuchs On BEST ANSWER

Why your PHP script is failing:

If you take a look at your error response from PHP:

PHP Warning: file_get_contents(https://translate.google.com/translate_tts?ie=utf-8&q=the+brown+fox+jumped+over+the+lazy+dog)

You'll notice that the url file_get_contents is requesting does not contain a tl parameter. This is causing a 404 to be returned. You can visit the page directly in your browser:

https://translate.google.com/translate_tts?ie=utf-8&q=the+brown+fox+jumped+over+the+lazy+dog

The above returns a 404 response :(

https://translate.google.com/translate_tts?ie=utf-8&q=the+brown+fox+jumped+over+the+lazy+dog&tl=en

But after we add a nice new shiny tl=en parameter, it works :).

2
turutosiya On

As you can see in this fiddle - http://jsfiddle.net/patridge/h4Lvp/, You can overwrite header values by calling setRequestHeader .

But, some headers are blocked to be overritten by the browsers.

/*global jQuery*/
(function ($) {
    $.ajaxSetup({
        "beforeSend": function(xhr) {
            // Works fine.
            xhr.setRequestHeader("X-Requested-With", {
                toString: function() {
                    return "";
                }
            });
            // Logs error on Chrome (probably others) as "Refused to set unsafe header "Referer".
            xhr.setRequestHeader("Referer", {
                toString: function() {
                    return "";
                }
            });
        }
    });
}(jQuery));

jQuery(function () {
    $.ajax({
        url: "http://fiddle.jshell.net/",
        dataType: "html"
    }).done(function (data) {
        $("<div>").text("ajax success").appendTo("body");
    });
});