1

Is there any way to have an Arduino web server redirect the client to a file on the SD card only if the client is using a mobile browser?

(My arduino server is already successfully serving pages on http://192.168.0.180, and successfully processes GET requests).

I was thinking of having this javascript code on the main page that's served by the arduino:

<script type="text/javascript">
  <!--
  if (screen.width <= 800) {
    window.location = "http://192.168.0.180?mobile";
  }
  //-->
</script>

My first thought was that maybe it's possible for the server to process that GET request and then serve a page from the SD card, instead of the regular page it serves.

Do you think this is possible, and how would you recommend to do it?

2

Yes, it is perfectly possible. you just have to look at the right bits.

Fundamentally there is no difference between an Arduino and any other website, it's just somewhat simpler in how it operates.

All browsers follow the same rules - if they didn't they wouldn't work on the web. Two of the rules you are interested in are:

  • Browsers identify themselves along with their OS.
  • Browsers respond to the "result" code the website provides in a specific way.

Besides the GET request a browser also sends a list of headers. These contain lots of extra information about the request, including the domain name of the website that is being accessed (so the web server knows which site you want - it's not one webserver per site, that would be impractical. For instance, the request to show this page from Firefox on Linux has these headers:

Host: arduino.stackexchange.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.6.0
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Accept-Language: en-gb,en;q=0.5 
Accept-Encoding: gzip, deflate
Cookie: (I won't bore you with this lot)
Connection: keep-alive

The header of note is the User-Agent: one. That tells the web server that I am using firefox from a 64-bit Intel Linux computer. If I were to do it from my Android phone it would tell you it's from Chrome on Android.

By looking for that header and parsing it for certain keywords you can find if you're serving to a mobile device or not.

Now the second bullet above - browsers respond to the response code in different ways. Normally you send the response code 200 which means "I accepted your request and here is the page you asked for". Another response code that is useful is code 301 which means "The page you asked for isn't at this address any more - here is the new address you should go to instead". That will then cause the browser to go to the newly provided address instead.

So instead of responding with

HTTP/1.0 200 OK
Content-type: text/html

<web page content here>

You could instead respond with:

HTTP/1.0 301 Moved Permanently
Location: http://myarduino.local/mobile

And the browser will redirect to the new address you give in the Location: response header.

The full list of response codes is here: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

If you want to avoid the overhead of a browser redirect you can just serve different data to the browser depending on what the User-Agent header specifies. After all, it's entirely down to you what is sent as the content of the page. Whether you get that from purely programmatical means, or by reading a file off an SD card, is entirely up to you.

| improve this answer | |
  • Does it make sense that serving a file from the SD card will be noticeably slower than just using "client.println" statements to serve the page? This is the code I'm using to read the file from the card (using the SDfat library, which is supposed to be faster than the main SD library): char c; while ((c = mobileFile.read()) >= 0) { client.write(c); } edit: sorry I couldn't figure out how to properly format the code in the comments section. – Jerry Jul 17 '15 at 13:53
  • It depends how big the file is. If it's a large file, like an image or lots of static text, then a file on the SD makes sense. If it's just a few bytes then there's no point in using the SD. – Majenko Jul 17 '15 at 13:58
  • Thanks! I ended up moving both files from the SD card onto the main program, because it ended up to be noticeably faster. It's big and clunky, but at least it does what I need it to do. :) – Jerry Jul 17 '15 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.