Appearance
AJAX
AJAX is not a specification of JavaScript; it is simply an abbreviation coined by a guy: Asynchronous JavaScript and XML, which means executing asynchronous network requests using JavaScript.
If you carefully observe the submission of a form, you'll notice that once the user clicks the "Submit" button, the form begins to submit, and the browser refreshes the page, then informs you on the new page whether the operation was successful or failed. If, unfortunately, the network is too slow or for other reasons, you may end up with a 404 page.
This is how the web operates: one HTTP request corresponds to one page.
If you want to keep the user on the current page while sending a new HTTP request, you must use JavaScript to send this new request. After receiving the data, JavaScript updates the page, allowing the user to feel as though they are still on the current page, but the data can continuously update.
The first large-scale use of AJAX was Gmail, where all data updates after the initial page load rely on AJAX.
Writing complete AJAX code in JavaScript is not complicated, but it is important to note that AJAX requests are executed asynchronously, which means you need a callback function to obtain the response.
In modern browsers, AJAX is primarily based on the XMLHttpRequest object. If you don't consider compatibility issues with early browsers, modern browsers also provide native support with the Fetch API, which offers a Promise-based approach. Here is the code to send an HTTP request using the Fetch API:
javascript
async function get(url) {
let resp = await fetch(url);
let result = await resp.text();
return result;
}
// Sending an asynchronous request:
get('./content.html').then(data => {
let textarea = document.getElementById('fetch-response-text');
textarea.value = data;
});
Fetch Response Result:
Using the Fetch API with async syntax simplifies the code.
For detailed usage of the Fetch API, refer to the MDN documentation.
Security Restrictions
The URL in the code above uses a relative path. If you change it to 'https://www.sina.com.cn/' and run it, it will definitely throw an error. You can also see the error message in the Chrome console.
This is due to the browser's same-origin policy. By default, when JavaScript sends AJAX requests, the domain of the URL must match exactly with the current page.
Exact matching means the domain must be the same (www.example.com and example.com are different), the protocol must be the same (http and https are different), and the port number must be the same (the default port for http is :80, which is different from :8080). Some browsers are a bit lenient and allow different ports, but most browsers strictly adhere to this restriction.
So, does this mean JavaScript cannot request URLs from other domains (i.e., other websites)? There are still methods available, roughly including the following:
Sending HTTP requests through the Flash plugin, which can bypass the browser's security restrictions, but Flash must be installed and interacted with. However, using Flash is cumbersome and is becoming less common.
Setting up a proxy server under the same origin domain to forward requests, where JavaScript sends requests to the proxy server:
'/proxy?url=https://www.sina.com.cn'
The proxy server then returns the results, complying with the browser's same-origin policy. The downside of this approach is that it requires additional server-side development.
The third method is called JSONP, which has a limitation: it can only use GET requests and requires the return of JavaScript. This method actually utilizes the browser's allowance for cross-domain references of JavaScript resources:
html
<html>
<head>
<script src="http://example.com/abc.js"></script>
...
</head>
<body>
...
</body>
</html>
JSONP usually returns in the form of a function call, for example, the returned JavaScript content looks like:
javascript
foo('data');
This way, if we prepare the foo()
function in advance on the page, and then dynamically add a <script>
tag to the page, it's equivalent to dynamically retrieving the external JavaScript resource and waiting for the callback.
CORS
If the browser supports HTML5, you can use a new cross-origin strategy: CORS.
CORS stands for Cross-Origin Resource Sharing, which is defined by the HTML5 specification for how to access resources across origins.
Before understanding CORS, we first need to clarify the concept:
Origin refers to the current domain, which is the domain of the browser's current page. When JavaScript sends a request to an external domain (like sina.com), the browser checks the response for Access-Control-Allow-Origin
to see if it includes the current domain. If it does, the cross-origin request is successful; if it doesn't, the request fails, and JavaScript cannot access any data from the response.
To illustrate this:
GET /res/abc.data
Host: sina.com
┌──────┐ Origin: http://my.com ┌────────┐
│my.com│───────────────────────────────────────────▶│sina.com│
│ │◀───────────────────────────────────────────│ │
└──────┘ HTTP/1.1 200 OK └────────┘
Access-Control-Allow-Origin: http://my.com
Content-Type: text/xml
<xml data...>
Assuming the current domain is my.com and the external domain is sina.com, as long as the response header Access-Control-Allow-Origin
is set to http://my.com
, or *
, the request can succeed.
Thus, whether cross-origin succeeds depends on whether the other server is willing to set a correct Access-Control-Allow-Origin
, with the decision always resting with the other party.
The above type of cross-origin request is known as a "simple request." Simple requests include GET, HEAD, and POST (with the POST Content-Type
limited to application/x-www-form-urlencoded
, multipart/form-data
, and text/plain
), and cannot include any custom headers (e.g., X-Custom: 12345
). This usually satisfies 90% of needs.
Regardless of whether you need to use JavaScript to make cross-origin requests through CORS, you should understand the principles of CORS. The latest browsers fully support HTML5. When referencing external resources, besides JavaScript and CSS, CORS validation is required. For example, when you reference a font file from a third-party CDN:
css
/* CSS */
@font-face {
font-family: 'FontAwesome';
src: url('http://cdn.com/fonts/fontawesome.ttf') format('truetype');
}
If the CDN provider does not correctly set Access-Control-Allow-Origin
, the browser will be unable to load the font resource.
For PUT, DELETE, and other types such as application/json
POST requests, before sending the AJAX request, the browser will first send an OPTIONS request (known as a preflight request) to the URL to inquire whether the target server accepts:
OPTIONS /path/to/resource HTTP/1.1
Host: bar.com
Origin: http://my.com
Access-Control-Request-Method: POST
The server must respond and explicitly state the allowed methods:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my.com
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
Access-Control-Max-Age: 86400
The browser checks that the Access-Control-Allow-Methods
header in the server's response includes the method intended for the AJAX request before continuing; otherwise, it will throw an error.
Since it is common to send JSON-formatted data via POST and PUT in REST, correct handling of cross-origin POST and PUT requests requires the server to respond properly to OPTIONS requests.
For those who wish to delve deeper into CORS, please refer to the MDN documentation and W3C documentation.