AngularJS SPA 应用中跨域请求的解决方案

在 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