Introduction
I'm writing a script that will alter the way a person views 4chan, when inside a thread, as well as adding some functionality.
In a 4chan thread, when you upload an image, the server will generate a thumbnail with the same name as the original file and also save that image for people to view, but with the name being the unix timestamp. When you click the thumbnail, its src
is changed to its parent's href
, meaning the name of the image is merely the timestamp, and not a useful name at all.
There are two problems with this
- When the thread has 404'd, there is a chance that you can't open the image anymore, since it has been removed from the server.
- The name of the image you download doesn't match the displayed name.
In this SO answer, you can see that the only lossless method that is also able to handle all types of files (I should be able to load jpg, png, gif and webm) is doing a query to the server, asking for the file, reading it and converting it to a data URI. When the image is cached inside the src
attribute, I can (according to this SO answer) simply add a download
attribute with the original filename, and my two points will be resolved.
The problem
I'm injecting the following script into 4chan with Styler, a Chrome extension.
$(function(){
if ($('body').hasClass('is_thread')) {
$.getScript("http://my.url/updater.js").done(function() {
$('html').addClass('done')
}).fail(function() {
$('html').addClass('done failed')
})
}
})
The script at my url is then loaded into the document itself, and does its own thing from there on (I plan on sharing the code with some people, that's why I've (temporarily) put the script on a server).
Inside the script there is a part that loops over all new posts and tries to request the file again.
var $media = $post.find('img, video')
if ($media.length) {
$.ajax({
url: $media.parent().attr('href'),
method: 'GET',
success: function (data) {
console.log(data)
},
error: function () {
console.log('error')
}
})
}
The AJAX call is being made, but the following error occurs:
XMLHttpRequest cannot load http://i.4cdn.org/b/123456789.jpg. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://boards.4chan.org' is therefore not allowed access.
When Adding the following to the call
headers: {
'Access-Control-Allow-Origin': 'http://boards.4chan.org'
}
I get the following error:
XMLHttpRequest cannot load http://i.4cdn.org/b/123456789.jpg. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://boards.4chan.org' is therefore not allowed access. The response had HTTP status code 405.
I am testing this on the http server and have also tried setting it to *
, https...
and http(s)...
, but no luck.
From the 4chan API:
CORS is supported with an origin of http(s)://boards.4chan.org
Does anybody know how I can fix this? I know there is a way to convert img src
es to data URI with canvas
, but that can be lossy and is limited to jpg, png and webp (in Chrome). I've settled on this method, since the API specifically states that CORS should be enabled for http://boards.4chan.org.
If you want to do the same thing I'm doing, you will have to install Styler, copy the code and upload a file to a server. Here is a minimal updater.js file.
var jq
;(function () {
var script = document.createElement('script')
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'
script.type = 'text/javascript'
script.onload = function () {
jq = window.jQuery.noConflict()
jq('.postContainer.replyContainer').each(function () {
var $post = jq(this)
var $media = $post.find('img, video')
if ($media.length) {
jq.ajax({
url: $media.parent().attr('href'),
method: 'GET',
headers: {
'Access-Control-Allow-Origin': 'http://boards.4chan.org'
},
success: function (data) {
console.log(data)
},
error: function () {
console.log('error')
}
})
}
})
}
document.getElementsByTagName('head')[0].appendChild(script)
})()