Switching between Youku and YouTube based on whether you're in China

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Switching between Youku and YouTube based on whether you're in China



I'm hosting a conference website where I want to embed a Youku video if you're in China and a YouTube video otherwise. The conference website is being served through a CDN inside the Great Firewall. I was given the code below to switch between internal and external versions of Youku.



Unfortunately, ipinfo.io does not seem to be accessible inside the Great Firewall, so the code times out after 10 seconds.



I've considered rewriting the page to use a Youku video by default, writing a small, non-blocking JavaScript function that tries to reach YouTube. If it can, replace the Youku with YouTube. If it can't, exit harmlessly. That way, the reachability of YouTube becomes the key test, not whether you're in China.



Alternatively, I've thought of hosting the video on my site, so that it will be replicated via the CDN inside the Great Firewall. However, that would mean that the video would always be downloaded at full resolution, even if you're on a slow connection.



Any better suggestions on how to switch between Youku and Youtube, or more generally have a video playable both inside and outside China?


jQuery.get("https://ipinfo.io", function(response) {
var country = response.country;

if(country == 'CN') {
youku.attr('src',chinaVideo)
} else {
youku.attr('src',generalVideo)
}
}, "jsonp");



This question has not received enough attention.



I'd love to hear from anyone with actual experience dealing with Great Firewall issues.





By keeping a common code base for all, you can make a separate cartridge for china, and write the youku code for your video in that cartridge, whenever user hits the URL, if the URL contains the id for the Chinese locale, then that code can override the default code.
– Code_Ninja
2 days ago





You should check for it only once and keep the result in a cookie, so a visitor only needs to wait for the first time he visits the site. If this video is not on the front page, by the time he makes it to the conference video, you can have it checked trying to access youtube and set the cookie.
– Munim Munna
yesterday





Thanks, but video is only on the front page.
– dankohn
21 hours ago





Don't you have CDN settings for that? Can you just push the youku-first version of scripts to CDN nodes near China users?
– amankkg
19 hours ago






5 Answers
5



Here's the JavaScript we're going with:


<script type="text/javascript">
var country = '',
youku = jQuery('#youku');

jQuery.get("https://ipinfo.io", function(response) {
var country = response.country;

if(country != 'CN') {
youku.attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
}
}, "jsonp");



We're including the Youku link in the HTML and switching to YouTube if country is not China. This still works if connecting to ipinfo.io times out, which sometimes happens in China.





Not sure why this is getting flagged.. it sure looks to me like he's posting an answer to his own question.
– Grant Winney
19 hours ago





@GrantWinney, it looks like an answer until you read the question.
– Munim Munna
14 hours ago





@Munim It's an answer. He's grabbing the #youku element (which, from reading his question, presumably points to the Youku video to start with). If the call to "ipinfo.io" times out, nothing changes. If the call to "ipinfo.io" works, and the country is anything but China, then the Youku video is replaced with a YouTube video. This is what he suggested he might do, in the third paragraph of his question.
– Grant Winney
11 hours ago







@GrantWinney the way OP is currently doing it is not an answer, it is part of the question. And I don't think OP was asking how can i select the jQuery element, please don't judge a question just reading the title.
– Munim Munna
11 hours ago





It is the answer we're planning to go with. I remain open to hearing a better one.
– dankohn
8 hours ago



Your current solution is not ideal as it depends on the GET request timing out, which is going to slow things down. Since the issue largely revolves around ipinfo.io being blocked in China, it's likely that an effective solution would involve an IP identification service based within China.


ipinfo.io



Try using http://www.ip138.com/. Google Translate works well enough to read it in English. There doesn't seem to be a formal JSON API, but you can hit http://www.ip138.com/ips138.asp?ip=<IP_ADDRESS_HERE> and get the location info.


http://www.ip138.com/


http://www.ip138.com/ips138.asp?ip=<IP_ADDRESS_HERE>



To do so, navigate the DOM with jQuery (since you're already using it) to the line with 本站数据:, which will precede the name of the country. I think the selector for that as the page is currently constructed is simply $( "li" ).first(). Extract the string after the colon and the POST it to the Google Translate API to get the country name in English and voila! You have a faster and more reliable (if considerably more complicated) way to see if a visitor is in China or not.


本站数据:


$( "li" ).first()



EDIT: It is not entirely clear if you possess the user's IP address beforehand. If not, you can use a similar method with https://geoiptool.com/zh/, which is also based within China and thus not blocked. I'm happy to flesh this part out as needed.


https://geoiptool.com/zh/



It is better to specifically check if YouTube is blocked in user's network rather than filtering out country based on IP which is never 100% reliable. This way it will even work in any school/office environment where YouTube could be blocked by network administrator for any reason.



This is the best answer I could find in this regard which tries to load the favicon of YouTube via JavaScript. If it succeeds to download that tiny image, YouTube is accessible. The image is only 0.2 kilobytes of download and it is most likely already cached by any user who ever visited YouTube.


favicon



That means the result is almost instantaneous for users with YouTube access and will take few seconds for users with blocked firewalls. The code is simple:


jQuery(function(){
var youku = jQuery('#youku');
var image = new Image();
image.onload = function(){
youku.attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
};
image.onerror = function(){
youku.attr('src','https://www.youku.com/embed/K3cEE5h7c1s')
};
image.src = "https://youtube.com/favicon.ico";
});



This one is a better solution than stated above as it does not wait for document.ready event of jQuery, the image starts to load instantly.


document.ready


(function(){
var image = new Image();
image.onload = function(){
jQuery(function(){
jQuery('#youku').attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
});
};
image.onerror = function(){
jQuery(function(){
jQuery('#youku').attr('src','https://www.youku.com/embed/K3cEE5h7c1s')
});
};
image.src = "https://youtube.com/favicon.ico";
})();



Any better suggestions on how to switch between Youku and Youtube, or
more generally have a video playable both inside and outside China?



I'd suggest taking a look at Alibaba Cloud. They have a bunch of services, but AFAIK there is no free plan.
Since I'm not familiar with other cloud providers for China, let me describe a solution for Alibaba Cloud.



I see two possible options for you:



What about using the client's time zone? While not perfect, it would allow you to avoid relying on timeouts or any geoip service requests altogether.




console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)



This is reasonably well-supported in modern browsers. In China, it should return the IANA time zone for China: "Asia/Shanghai".



There are also libraries (jsTimezoneDetect and moment-timezone) that combine the above along with the getTimezoneOffset function of Date across multiple points in time, to make an educated guess of time zone, which may yield better results with older browsers:


getTimezoneOffset


Date




console.log(jstz.determine().name());
console.log(moment.tz.guess());


<script src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.5/moment-timezone-with-data-2010-2020.min.js"></script>



For my part, I'd probably try detecting the time zone as "Asia/Shanghai" and fallback to a time zone offset of "UTC+8" (time zone offset alone will catch more than mainland China but I would imagine that's an acceptable overreach for a fallback strategy), e.g.:




var ianaTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
var offset = new Date().getTimezoneOffset();

if (ianaTz === "Asia/Shanghai" || (ianaTz == null && offset/60 == -8)) {
console.log("We'll assume China");
} else {
console.log("not China");
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

How to scale/resize CVPixelBufferRef in objective C, iOS