AJAX 访问其他网站
一、AJAX
AJAX(Asynchronous JavaScript and XML)是一种用于创建异步 Web 应用程序的技术,它允许网页在不重新加载整个页面的情况下,与服务器进行数据交互,通过 AJAX,可以从服务器获取数据并更新网页的某个部分,从而提供更流畅的用户体验。
(一)工作原理
AJAX 使用XMLHttpRequest
对象(在现代浏览器中也可以使用fetch
API)向服务器发送请求,当服务器响应后,JavaScript 可以处理返回的数据,并根据需要更新网页内容,整个过程是异步的,即不会阻塞网页的其他部分运行。
(二)优势
用户体验好:无需刷新整个页面,减少了等待时间,使用户操作更加流畅。
服务器负载低:只传输必要的数据,相比传统的方式可以减少网络流量和服务器压力。
二、跨域问题
当我们使用 AJAX 访问其他网站时,可能会遇到跨域问题,这是因为浏览器出于安全考虑,限制了不同源之间的资源共享,如果尝试从一个域名访问另一个域名的资源,浏览器会阻止这种请求,除非服务器进行了相应的配置。
(一)同源策略
同源策略是指协议、域名和端口都相同的两个 URL 被认为是同源的。http://example.com:80
和https://example.com:443
就不属于同源。
(二)解决跨域的方法
1、JSONP(JSON with Padding)
原理:JSONP 是一种利用<script>
标签没有跨域限制的特性来实现跨域数据交互的方法,通过将数据包装在一个回调函数中,以<script>
标签的形式引入页面,从而避免了同源策略的限制。
示例代码:
function jsonpCallback(data) { console.log(data); } function jsonpRequest(url) { var script = document.createElement('script'); script.src = url + '?callback=jsonpCallback'; document.body.appendChild(script); } jsonpRequest('https://otherdomain.com/api/data');
2、CORS(Cross-Origin Resource Sharing)
原理:CORS 是一种由服务器端设置头信息来允许跨域请求的机制,服务器需要在响应头中包含适当的字段,如Access-Control-Allow-Origin
,以指定允许访问该资源的域名。
示例代码(服务器端):
from flask import Flask, Response app = Flask(__name__) @app.route('/api/data') def get_data(): response = Response("Some data") response.headers['Access-Control-Allow-Origin'] = '' return response if __name__ == '__main__': app.run()
示例代码(客户端):
var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://otherdomain.com/api/data', true); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); } }; xhr.send();
3、服务器代理
原理:在自己的服务器上设置一个代理接口,通过该接口转发请求到目标网站,这样,从客户端来看,请求是发送到自己的服务器,不存在跨域问题,而服务器再将请求转发给目标网站,并将返回的结果返回给客户端。
示例代码(服务器端 Node.js):
const express = require('express'); const request = require('request'); const app = express(); app.get('/proxy', function(req, res) { request({url: 'https://otherdomain.com/api/data'}) .pipe(res); }); app.listen(3000);
示例代码(客户端):
var xhr = new XMLHttpRequest(); xhr.open('GET', '/proxy', true); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); } }; xhr.send();
三、AJAX 访问其他网站的步骤(以fetch
API 为例)
1、创建请求配置对象:指定请求的方法(如GET
、POST
等)、请求的 URL、请求头等信息。
2、发送请求:使用fetch
函数发送请求,并返回一个 Promise 对象。
3、处理响应:在 Promise 的then
方法中处理服务器返回的响应数据,如果请求失败,可以在catch
方法中处理错误。
(一)示例代码
fetch('https://otherdomain.com/api/data', { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } return response.json(); }) .then(data => { console.log(data); }) .catch(error => { console.error('There has been a problem with your fetch operation:', error); });
四、相关问题与解答
(一)问题 1:为什么使用 JSONP 时只能发送 GET 请求?
解答:因为 JSONP 是通过<script>
标签引入脚本文件来实现跨域的,而<script>
标签的 src 属性只能指定一个 URL,无法像XMLHttpRequest
或fetch
那样设置请求体来发送 POST 等其他类型的请求,JSONP 只能用于发送 GET 请求。
(二)问题 2:CORS 中的预检请求(Preflight Request)是什么?什么时候会发生预检请求?
解答:预检请求是一种额外的 HTTP 请求,用于检查目标服务器是否允许实际的跨域请求,当使用某些 HTTP 方法(如PUT
、DELETE
、PATCH
等)或者在请求头中设置了特定的字段(如自定义头、Content-Type
为非application/x-www-form-urlencoded
、multipart/form-data
、text/plain
之外的值等)时,浏览器会自动发送一个预检请求到目标服务器,预检请求的方法是OPTIONS
,它会询问服务器是否允许实际的请求方法和请求头,如果服务器在响应中返回允许的信息,浏览器才会发送实际的请求;否则,浏览器会阻止实际的请求并抛出错误。
原创文章,作者:未希,如若转载,请注明出处:https://www.kdun.com/ask/1650108.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复