Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Debugging Ajax Calls

Debugging Ajax Calls

An introduction to debugging Ajax calls with cURL and the Chrome Network Tools.

These slides were used to create these videos:

https://www.youtube.com/watch?v=9JzQPrGaMhw&t=73s
https://www.youtube.com/watch?v=RcrW7PCzx3Q

Toby Ho

July 17, 2017
Tweet

More Decks by Toby Ho

Other Decks in Programming

Transcript

  1. Overview • HTTP request/response • Chrome Network Tools • Filtering

    request/responses • Request/response details • Copying and replaying • Inspecting Errors • XHR breakpoints • What are we doing?
  2. A HTTP request/response $ curl http://chad.is/ -v Curl (sometimes spelled

    cURL) is a command-line based tool for making HTTP requests
  3. A HTTP request/response $ curl http://chad.is/ -v * Hostname was

    NOT found in DNS cache * Trying 192.30.252.153... * Connected to chad.is (192.30.252.153) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.37.1 > Host: chad.is > Accept: */* > < HTTP/1.1 200 OK * Server GitHub.com is not blacklisted < Server: GitHub.com < Date: Sun, 16 Jul 2017 06:05:39 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 2303 < Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT < Access-Control-Allow-Origin: * < Expires: Sun, 16 Jul 2017 06:15:39 GMT < Cache-Control: max-age=600 < Accept-Ranges: bytes < X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 < <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; …
  4. The Request $ curl http://chad.is/ -v * Hostname was NOT

    found in DNS cache * Trying 192.30.252.153... * Connected to chad.is (192.30.252.153) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.37.1 > Host: chad.is > Accept: */* > < HTTP/1.1 200 OK * Server GitHub.com is not blacklisted < Server: GitHub.com < Date: Sun, 16 Jul 2017 06:05:39 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 2303 < Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT < Access-Control-Allow-Origin: * < Expires: Sun, 16 Jul 2017 06:15:39 GMT < Cache-Control: max-age=600 < Accept-Ranges: bytes < X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 < <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; …
  5. The Response $ curl http://chad.is/ -v * Hostname was NOT

    found in DNS cache * Trying 192.30.252.153... * Connected to chad.is (192.30.252.153) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.37.1 > Host: chad.is > Accept: */* > < HTTP/1.1 200 OK * Server GitHub.com is not blacklisted < Server: GitHub.com < Date: Sun, 16 Jul 2017 06:05:39 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 2303 < Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT < Access-Control-Allow-Origin: * < Expires: Sun, 16 Jul 2017 06:15:39 GMT < Cache-Control: max-age=600 < Accept-Ranges: bytes < X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 < <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; …
  6. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; …
  7. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … HTTP version
  8. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … Status Code and message
  9. Response: The Status Code 1xx Informational responses. 2xx Success. 3xx

    Redirection. 4xx Client errors. 5xx Server errors.
  10. Error Status Codes 400 - Bad Request (it was your

    fault) 401 - Unauthorized 403 - Forbidden 404 - Not Found 405 - Method Not Allowed (maybe you are using GET where you are supposed to use POST) 500 - Internal Server Error (it was our fault) 501 - Not Implemented 502 - Bad Gateway (you are accessing this through a proxy server, and the proxy server got an error from the original server) more…
  11. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … Headers
  12. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … Blank line
  13. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … Body
  14. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … Body More content omitted for brevity
  15. The Response: In Detail HTTP/1.1 200 OK Server: GitHub.com Date:

    Sun, 16 Jul 2017 06:05:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 2303 Last-Modified: Sat, 08 Jul 2017 09:09:13 GMT Access-Control-Allow-Origin: * Expires: Sun, 16 Jul 2017 06:15:39 GMT Cache-Control: max-age=600 Accept-Ranges: bytes X-GitHub-Request-Id: 5FE0:0DE8:A7B67D:EC9F7F:596B0233 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Chad Mazzola lives in Stockholm, Sweden."> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Chad Mazzola</title> <link href="https://fonts.googleapis.com/css?family=Karla:400,400i,700,700i" rel="stylesheet"> <link rel="stylesheet" href="/stylesheets/application.css"> <link href="/feeds/articles.xml" rel="alternate" title="RSS feed" type="application/atom+xml"> <script type="text/javascript"> var _gaq = _gaq || []; … This is HTML Mime Type for HTML
  16. Response Types • HTML - text/html • CSS - text/css

    • JavaScript - text/javascript • JSON - application/json
  17. Refresh the page and record all the requests issued as

    result of loading the page Click to reload
  18. Now you try! Open a web site of your choice

    and look at all requests issued in order to load the page, and the waterfall graph.
  19. Open in New Tab Open the URL of the request

    in a new tab. Great for GET requests
  20. Copy as cURL Copy a cURL command to your clipboard

    which you can use in the terminal!!!
  21. Copy as cURL Will preserve all headers/cookies so will work

    even when authentication is required by the backend
  22. Now you try!! • Open a web site / web

    app of your choice • Look at all request/responses • Use the filter panel to look at only the Ajax request/responses • Use the text filter to view only the requests with a particular substring in the URL • Select a particular request/response and inspect the, headers tab, preview tab, response tab, and the timing tab • Re-issue the request by copying its URL, a cURL command, or by replaying the request
  23. Coming from the Console Tab When you encounter an error

    response, you will see it in your console as well, click on it to switch to the network panel
  24. XHR (Ajax) Breakpoints Use if you don’t know and want

    to find out what line of code initiated a particular request
  25. First come up with a substring to filter down to

    just the request(s) you are interested in
  26. Now induce the request again, in my case, I had

    to reload the page. Now the debugger has paused on the line that induces the request
  27. Being dropped into jQuery’s source code might seem intimidating, but

    actually, we can relate this to the application code by looking down in the call stack
  28. Because we are still in the debugger session, we can

    see the variables in the frame, such as city, which has the value “Atlanta”
  29. Now you try!! • Induce an error - 4xx or

    5xx (by changing the frontend or backend code) • Set up and test out an XHR breakpoint
  30. Debugging: Isolate the Problem • Which request caused the problem?

    • Is it caused by • front-end code • error in the way the request is sent • both the request and response look good, so problem must be with elsewhere in the front-end • back-end code
  31. Look at the Headers tab in request/response details. Optionally, copy

    the cURL command and try to change the command’s URL to fix the request until the response is good
  32. If you don’t know what’s the problematic request • Is

    there a request with an error response? Look in the console or look through the list of requests in the Network Tools • Use your knowledge of the code. Which request is supposed to retrieve the data that’s not being displayed correctly, or cause a change to the database correctly?
  33. Performance Tuning • Look at the waterfall graph • Look

    at the response times - are individual responses taking a long time? • Look at the number of requests - are there many requests? the fewer the better (Browsers can only send 3-6 requests in parallel) • What are the requests doing? Can we eliminate some of them by batch multiple requests into one
  34. Now you try!! • Think of a problem with your

    app that could benefit from using the network tools • Use Chrome Network Tools to isolate the problem