8

Okay here it is: (I am changing this post's content for the third time to explain better)

My website is an Image Hosting website, meaning the user can upload to my website and receive a direct link to his/her uploaded image.

I need some sort of API/way to communicate from my site with my users. I want users that are registered to my website be able to UPLOAD IMAGES from their website to my Image Host without them having to leave their own website (AJAX, iFrame, cURL, JSON, whatever it takes).

The request to my website should include a &request=api paramater so the user gets plain text returned from my upload.php script. This way I think I ensure an easier way of grabbing data/output from my site.

So, basically, AFTER a POST/FILES request from the user's site to my Image Host, they receive link(s) from my upload processing script, which they need to retrieve and then use for their own needs.

My question is: My registered user sends a file to my server WITHOUT reloading the page and gets back the URL(s) to that image. How do I do this?


What I have tried:

All my tries were blockages with no continuing.

First, I added two new columns to two different tables. My users table received an api_key column, which was intended to store an API key if the user actually signs up for it. The other column is_api was added to the table where I store image information, only registered users have their images stored in the database. With this new column (which was type TINYINT) I wanted to check that the image coming from the user was (or was not) added/uploaded via the API.

User sends a request to my Image Host with these parameters: upload.php?submit=true&action=upload&request=api&key=_SOME_API_KEY_. I take the API key and check whom it belongs to -> Retrieve an user id based on that key -> I store the image to my server -> I store image information in my database (have an user id now) -> I echo out the URL.

My failures here were:

  • I couldn't send ANYTHING from the 3rd party website to my Image Host asynchronously
  • I couldn't receive anything back to my 3rd party website.

Why these failures? Because I have no idea how to achieve these two most important steps.

One of my ideas to stop trying to send $_FILES[] to my Image Host, was trying to send an IMAGE STRING via POST to my server and create the image there myself. I couldn't do this either, it was just a thought of a guy who had time to think.

So, this is it: My big problem with no solution from myself.
If you need more information in order to help me out more easily, please ask.

Thank you.

Update

If I just could receive the file somehow (asynchronously) I'd register it in the database with the is_api field with a value of 1, to mark it as put via the API (external). This way, I could create a a new file named viewer.php maybe and it would accept some parameters too like viewer.php?request=api&key=_API_KEY_ and it would return a JSON page with the link to the latest image by that external api user. Retrieving the page via JSON by the 3rd party website would be quite easy. So, with this method, I basically just need to receive the image somehow in my Image Host and the retrieving part wouldn't be too hard. So how would I send an IMAGE STRING to my Image Host via POST?

If this new idea of mine is exploitable, please let me know.

Community
  • 1
  • 1
aborted
  • 4,481
  • 14
  • 69
  • 132
  • 1
    Did you try sending the link via JSON or XML to an Ajax client or did you send it to the Ajax client in straight text? – Josh Austin Feb 05 '13 at 22:45
  • I did not try anything with JSON, because I have no idea how to use it, hence the question. My AJAX knowledge is pretty limited too. – aborted Feb 05 '13 at 22:46
  • Sounds like it could be handled very simply in an iframe which contains a real form that posts back to the image host. It will look like ajax (as the iframe prevents the full page post) and you can return the links in the resultant page as the response directly to the iframe. – Gavin Feb 06 '13 at 19:37
  • @Gavin Could you show me an example of what you're saying? Maybe your answer would actually work and then I could accept it. – aborted Feb 06 '13 at 20:13
  • Take a look at this http://viralpatel.net/blogs/ajax-style-file-uploading-using-hidden-iframe/ – Gavin Feb 06 '13 at 20:21
  • I'm not sure if it's doable. It sounds like something that the browser would want to stop due to security concerns. The way I've seen it done is for the third-party server to accept the upload, then transfer it to the image hosting site server to server. The bandwidth between hosts is typically quite high so the overhead is acceptable. – cleong Feb 10 '13 at 14:05
  • @cleong I edited the question, please read it now. – aborted Feb 10 '13 at 14:41

5 Answers5

10

I am providing a script like this one to my users as a bridge to my website:

<?php 
$api_key = 'n8N9v0g9e7b1h0H4A7s2t6q5K8f07B6E4a5p2k4D6L2T1G4Y7I3z5Q5';
$uses_ajax = false;
$imgit = array('error' => true);

if (isset($_POST['imgit_request']))
{
    if ($_POST['imgit_request'] == 'upload')
    {
        $post_data = array(
            'submit'  => 'true',
            'action'  => 'upload',
            'request' => 'api',
            'api_key' => $api_key,
            'imagestr' => chunk_split(base64_encode(file_get_contents($_FILES['images']['tmp_name']))),
            'imagemime' => $_FILES['images']['type'],
            'imagename' => $_FILES['images']['name'],
            'imagesize' => $_FILES['images']['size'],
        );  
    }
    else if ($_POST['imgit_request'] == 'remote')
    {
        $post_data = array(
            'submit'  => 'true',
            'action'  => 'remote',
            'request' => 'api',
            'api_key' => $api_key,
            'links'   => $_POST['links'],
        );  
    }

    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => 'http://dugi/imgitv3/upload.php',
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $post_data,
    ));

    $resp = curl_exec($curl);
    curl_close($curl);

    if (strpos($resp, 'http://') !== false)
    {
        $imgit = array(
            'direct' => $resp,
            'thumb' => str_replace('/i/', '/t/', $resp),
            'error' => false,
        );

        if ($uses_ajax)
        {
            echo $imgit['direct'];  
        }
    }
    if (strpos($resp, 'http://') === false)
    {
        $imgit = array(
            'error' => $resp,
        );  
    }
}
?>

Then I do the rest of the processing in my website based on the information I receive. I will be updating this answer once I finish the complete API CP on my website, where the webmaster who is using the API can see what images have been uploaded via his website to my Image Host. From the script above, you can see an API key - it's unique for every user, the one above is just a sample.

For asynchronous I made it work by telling the users to use the jQuery Form plugin. It's a very handy plugin for submitting forms and I show the user how they would do it.

Thanks for everyone who tried to help me.

aborted
  • 4,481
  • 14
  • 69
  • 132
2

Try using

json_encode()

for the php side (don't forget to include a JSON mimetype header) of the link in question and

$.getJSON()

using jQuery on the receiving end. You can then put the resulting link in the div or paragraph (or whatever) you like. If the hyperlink is an already existing hyperlink being changed/updated, you can change the hyperlink with jQuery.

These links may help:

http://www.w3schools.com/jquery/ajax_getjson.asp

http://php.net/manual/en/function.json-encode.php

Community
  • 1
  • 1
Josh Austin
  • 740
  • 3
  • 14
1

Please take a look at my RestServer class on GitHub. It will allow you to turn any PHP class into a RESTful web service (returning JSON responses). JSON is the way to go for these types of responses and RestServer will take care of encoding your return objects as JSON before returning the data to the client.

You can make GET requests like http://mysite.com/myapi.php?method=sayHello&name=World where the query string requires a method name, and each param for that method. POST requests are also supported by simply changing your request to POST and including your params in the POST body.

It will automatically detect the params needed for the requested method. You could setup a secret API key and have that as a required param for each API method for authentication purposes.

class Hello
{
  public static function sayHello($name)
  {
    // RestServer will json_encode this array before returning it to the client.
    return array("Response" => "Hello, " . $name);
  }
}

$rest = new RestServer(Hello);
$rest->handle();

Then you would just make the call using $.getJSON with jQuery.

Jake Sankey
  • 4,977
  • 12
  • 39
  • 53
0

It sounds like they are using a web form, so you should strictly use POST. There is no getting round using a script somewhere if you want the client to send you a string (but why would you have them do this?).

If they are POST'ing a form, use the POST method, then have a server side script use PUT to write to a backend API server, which will return a JSON page with the link to the latest image.

If they are writing directly to the API, follow the same convention, except your user will use PUT directly (PUT isn't available in web forms, just POST and GET).

EDIT: I have a possible solution for you for the client-side using HTML5. You could put the image into an html5 canvas and convert the data into a string. Then just grab that string and POST it via the form. See this answer for more info on how to do this.

<label>Image File:</label><br/>
<input type="file" id="imageLoader" name="imageLoader"/>
<canvas id="imageCanvas"></canvas>
<script>
var imageLoader = document.getElementById('imageLoader');
    imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');


function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img,0,0);
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
     /** replace readAsDataURL() with something that will read it to a string.
     Reference: https://developer.mozilla.org/en-US/docs/DOM/FileReader **/
}
</script>

To summarize: put the image into the canvas DOM element, then convert the canvas data to a string.

Community
  • 1
  • 1
taco
  • 1,367
  • 17
  • 32
0

How about receiving the original request from 3rd party site to your image host using your upload.php thru POST, then inside upload.php you route the request to another page using AJAX call. In this way it will be asynchronous. I think it is achievable this way.

TravellingGeek
  • 1,581
  • 11
  • 16