在 AngularJS 的单页应用程序中,很少有一个应用程序只与它自己的后端 API 交互。通常情况下,应用程序需要与其他服务(如 Google 地图 API 或 Facebook API)进行跨域请求。但是跨域请求涉及到浏览器的同源策略(Same-Origin Policy),浏览器默认禁止从本地的一个 URL 发送 AJAX 请求到不同来源的服务器,这是为了防止 JavaScript 代码访问和操作不同域的 DOM,以及防止 CSRF(Cross-site request forgery)攻击。
在这篇文章中,我们将介绍一些解决方案来克服跨域请求问题。我们还将介绍 AngularJS 的解决方案和如何在 AngularJS 应用程序中使用它们。
JSONP
JSONP 是一种用于解决跨域请求的技术。它类似于对服务器发出动态脚本元素,但是返回的不是 JavaScript 代码而是包装在一个函数中的 JSON 数据。JSONP 请求没有跨域的限制,因为它们不是 AJAX 调用,而是将响应直接注入到页面中。
AngularJS 已经内置了 JSONP 提供者,它可以允许我们使用 JSONP 请求。
-------------------------------------------------------------------------- ----------------------- - -- ------ ---
其中的 'https://api.github.com/users/angular?callback=JSON_CALLBACK' 是我们要请求的 URL,回调参数可以在 URL 中指定或者使用 AngularJS 提供的默认回调名称 JSON_CALLBACK。
CORS
CORS(Cross-Origin Resource Sharing)是一种标准的跨域解决方案,它可以允许服务器授权一个网站去访问另一个网站的资源,也可以允许客户端 JavaScript 向不同的域提交 AJAX 请求。
在让服务器接受跨域请求之前,需要在应用程序的后端中实现 CORS。实现 CORS 时,服务器会添加一个 Access-Control-Allow-Origin 的 HTTP 头,以指定它允许哪些域(Origin)访问它的资源。可以使用 AngularJS 的默认 $http 提供者来发送 CORS 请求,请求将自动包含适当的 CORS HTTP 头。
------------------------------------------------- - -------- - ------------------------------ --- - ------------------------- - -- ------ ---
以上示例将使用 GET 方法发出对 https://api.github.com/users/angular 的跨域请求,响应将带有 Access-Control-Allow-Origin 头,允许任何来源的请求。
代理
代理方式是一种常见的解决跨域请求问题的方法,它也是一种在开发期间测试应用程序的有效方法。代理将请求发送到本地服务器(例如 Node.js)而不是直接发送到第三方服务,然后代理服务器将在后端更改请求头并将请求发送到第三方服务。取决于应用的类型,代理服务的实现可能会有所不同,例如在桌面应用程序中使用的代理可能与移动应用程序的有所不同。
下面这个示例使用 Grunt 来运行一个 Node.js 服务器,并利用代理路由,将请求转发到第三方服务。这个示例需要安装 grunt-contrib-connect、http-proxy、和 grunt-http-proxy 中间件。
-------------- - --------------- - ------------------ -------- - ------- - -------- - ----- ----- ----- ---- -- -------- ----------- ----------------- -------- - --- ----------- - --- --- ----- - --------------------------------- -- ------ --- -------- - ------------- - ------- -------------------------- ------------- ----- ------------ - -------- -- -- --------- ------- --- -- --------------- --------------------------- -- -------- ----------------------------------------------- -------------------------------------------------- ------ ------------ - - - - --- -------------------------------------------- ---------------------------- ------------------ ---------- --
在上面的示例中,我们将请求的 URL 前缀设置为 '/api'(行 12),然后创建一个使用 http-proxy-middleware 的代理路由(行 14 到 24)。代理会将所有以我们在本地应用程序中使用的 '/api' 为前缀的请求转发到指定的 API 地址上去。然后,应用程序的后端代码将从本地监听的 http://localhost:9000/api 向代理发送 AJAX 请求,这些请求被代理服务器转发到指定的 API 地址上。
在实际生产环境中,大多数情况下使用 Nginx 或 Apache 等服务器自身的反向代理功能,让服务器接受跨域请求。
结论
在 AngularJS 应用程序中,可以使用 JSONP、CORS 或代理方式来解决跨域请求问题。使用这些技术之前需要仔细熟悉浏览器的同源策略和如何使用 Angular 的 $http 服务和中间件来完成任务。
如果你正在从本地开发和测试应用程序,那么最好使用 Nginx 或 Apache 等服务器自带的反向代理功能来解决跨域请求,因为这是最灵活和可移植的解决方案,而且也是最接近生产环境的工作方式。
希望这篇文章能对你有所帮助!
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/671b107e9babaf620fa764ca