1. 程式人生 > >ionic解決跨域訪問

ionic解決跨域訪問

如果你通過 ionic serve 或者 ionic run 命令使用或 live reload 或者訪問過外部 API 結點,那麼你肯定遇到過 CORS 問題,譬如下面這樣:

XMLHttpRequest cannot load http://api.ionic.com/endpoint.
No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://localhost:8100' is therefore not allowed access.

那麼問題來了,什麼是 CORS 呢?又是什麼導致了這個問題嘞?

什麼是 CORS?

CORS=Cross origin resource sharing(跨域資源共享)

origin 就是你現在正在看的主站,你現在訪問的是
http://ionicframework.com/blog/handling-cors-issues-in-ionic,那麼 origin 就是ionicframework.com

如果說我們向 http://cors.api.com/api 發起一個 AJAX 請求,那麼 host origin 會由被瀏覽器自動列入CORS請求的 Orgin header 指定好了,由於ionicframework.comapi.com

的主機並不匹配,所以在一個HTTP OPTIONS請求報頭的 form 中我們所有從 ionicframework.com發起的訪問伺服器資源的請求必修得到伺服器的授權。

假如上面的請求出現錯誤(不被伺服器允許),那麼我們是無法從伺服器訪問到(api.com上的)資源的。

讓我們來看一下當你通過ionic serve, ionic run,ionic run -l來執行app的時候 origin 會是什麼。

瀏覽器中的執行

當你執行 ionic serve 時發生了什麼呢?

  • 啟動了一個本地 web 伺服器
  • 你的瀏覽器開啟並定位到本地伺服器地址

這讓你看著你的應用載入到你電腦上一個瀏覽器裡,地址是:http://localhost:8100

(如果你選擇了 localhost的話)。

你的 origin 就是localhost:8100
任何的傳送到其他不是 localhost:8100主機上的 AJAX 請求都會把localhost:8100作為他的 origin,這就會導致必須要經過一個 CORS 預檢來看是否可以訪問(非本機的)伺服器資源。

裝置上的執行

在裝置使用 ionic run執行

當你執行 ionic run 時發生了什麼呢?

  • app 所有的檔案被拷貝到裝置(或者模擬器)上。
  • app 執行起來,觸發手機/模擬器上的瀏覽器訪問已經被拷貝上去的檔案,

比如: file://some/path/www/index.html
因為你正在執行的 URI 是 file://,所以你的 origin 將不會存在,所以任何向外的請求都不再需要 CORS 請求。

在裝置使用 livereload 執行

當你執行 ionic run -l時又發生了什麼呢?

  • 啟動了一個本地伺服器
  • app 執行起來,觸發手機/模擬器上的一個瀏覽器通過

http://192.168.1.1:8100來執行檔案(你的 本地 ip 可能是其他的)。
你的 origin 就會是 192.168.1.1:8100
任何一個傳送到不是192.168.1.1:8100的伺服器上的 AJAX 請求都會需要進行 CORS 預檢請求來看是否可以訪問到該伺服器上的資源。

在 ionic 中解決 CORS 問題

CORS 問題只有在我們通過 ionic serve 或者 ionic run -l 來執行或測試應用的時候才會遇到。

解決這個問題有兩個辦法:

  1. 在你的 API 伺服器端允許所有的 origin,然而我們並不能控制我們訪問的所有的結點。我們需要的是一個不指定origin的請求。
  2. 我們可以通過使用代理伺服器來解決這個問題。

我們來看看 Ionic CLI 是怎樣提供了一個易配置的代理伺服器的。

Ionic CLI代理伺服器

關於代理的快速定義
在計算機網路中,代理伺服器就是一個伺服器(計算機系統或者應用程式),是客戶端發起的請求從其他伺服器尋求資源的中間橋樑。

我們為了避開 CORS 問題需要做的就是有一個代理伺服器,可以接收我們的請求,向 API 結點發出一個新的請求,接收結點響應,之後反饋給我們的應用,從而避開 CORS 問題。

Ionic CLI 就有給你提供一個代理伺服器從而避開所有可能會遇到的 CORS 問題的能力。

由於代理伺服器向你的目標主機發起了一個新的請求,所以就不會再有 origin,也就不再需要 CORS 了。要注意,在瀏覽器增加了 Origin header 是很重要的。

設定代理伺服器

注意,這些設定只有通過ionic serve 和 ionic run -l 執行應用才需要
首先我們需要在 ionic.project檔案中設定我們的代理,這會告訴我們的 Ionic 本地伺服器監聽這些地址,然後傳送這些請求到我們的目標地址上。

在我們的應用中,當執行 serve 或 run -l 時候,我們需要把要訪問的結點地址替換成代理伺服器的地址。替換地址的方法有兩個:

  • 使用gulp任務的 replace 模組來轉換出口地址會簡單一點。
  • 建議的方法是設定一個 Angular Constant 來定位到我們試圖代理的 API。

方法1:通過Angular Constant

這就是我們下面要採用的方法。我們會同時設定一個 Angular Service 來從 API結點 獲取資料。

設定代理路徑

比如說我們想要訪問 ·http://cors.api.com/api·,但並不允許我們來自 localhost:8100的 origin。
代理的設定包括兩件事兒:

  • 在你本地 Ionic 伺服器需要訪問的 path
  • 最終需要訪問API的 proxyUrl
{
  "name": "proxy-example",
  "app_id": "",
  "proxies": [
    {
      "path": "/api",
      "proxyUrl": "http://cors.api.com/api"
    }
  ]
  }

通過ionic serve啟動你的伺服器。
像我們上面指定的這樣,當你訪問 Ionic 伺服器地址 http://localhost:8100/api的時候,它會以你的名義訪問 http://cors.api.com/api。這樣,就不需要 CORS 了。

設定 Angular Constant

把你的 API結點設定成 Angular Constants是非常簡單的一件事兒。
下面我們就來把API結點指定成為我們的代理 URL。
之後(釋出時候)我們會把正式的地址作為 constant。

angular.module('starter', ['ionic', 'starter.controllers','starter.services'])
.constant('ApiEndpoint', {
  url: 'http://localhost:8100/api'
  })
// .constant('ApiEndpoint', {
//  url: 'http://cors.api.com/api'
// })

設定好之後你就能像下面這樣在應用中引入ApiEndpoint依賴,隨意呼叫這個constant了。

設定Angular Service

angular.module('starter.services', [])
//NOTE: We are including the constant `ApiEndpoint` to be used 
.factory('Api', function($http, ApiEndpoint) {
  console.log('ApiEndpoint', ApiEndpoint)

  var getApiData = function() {
    return $http.get(ApiEndpoint.url + '/tasks')
      .then(function(data) {
        console.log('Got some data: ', data);
        return data;
      });
  };

  return {
    getApiData: getApiData
  };
})

方法2:通過 Gulp 自動轉換地址

這個過程中,我們需要修改gulpfile.js來新增兩個任務:新增代理和移除代理。
首先安裝replace模組 - npm install –save replace

// npm install --save replace
var replace = require('replace');
var replaceFiles = ['./www/js/app.js'];

gulp.task('add-proxy', function() {
  return replace({
    regex: "http://cors.api.com/api",
    replacement: "http://localhost:8100/api",
    paths: replaceFiles,
    recursive: false,
    silent: false,
  });})

gulp.task('remove-proxy', function() {
  return replace({
    regex: "http://localhost:8100/api",
    replacement: "http://cors.api.com/api",
    paths: replaceFiles,
    recursive: false,
    silent: false,
  });
})

結語

本教程向你展示了一個解決通過ionic serve或ionic run -l命令執行應用時候遇到的 CORS 問題的方法。
我們知道在ionic serve和ionic run -l之間轉換 API 結點地址的時候可能會是個麻煩,比較建議的方法是啟動一個 gulp 程序。
解決 CORS 問題最簡單的方法是讓 API 提供者允許所有的 hosts,然後這事兒有點兒不太現實。
使用 Angular constant 和 replace 模組可以給我們一個避開 CORS 的折中的辦法。

相關推薦

ionic解決訪問

如果你通過 ionic serve 或者 ionic run 命令使用或 live reload 或者訪問過外部 API 結點,那麼你肯定遇到過 CORS 問題,譬如下面這樣: XMLHttpRequest cannot load http://api.i

伺服器端解決訪問

跨域是頁面js請求ajax,js所在html的url與請求api,不在同一個域名下,跨域解決的思路。 1、伺服器端響應頭允許請求的url,即響應輸出允許訪問的域名; 2、請求由伺服器轉發,使用閘道器或者nginx對請求進行重定向。 具體方案: 1、php 在responce的header中輸

學習通過後端配置cors遊覽器解決訪問

學習通過後端配置cors遊覽器解決跨域訪問 現在的遊覽器ie10以上的都可以瀏覽器直接發出CORS請求。體來說,就是在頭資訊之中,增加一個Origin欄位。然後node後端 router.get('/getData', function(req, res, next) { //設

java設定響應頭,解決訪問限制

public class testFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain)

Django解決訪問報錯/Cros問題

兩種方法: 拼資料 def myview(_request): response = HttpResponse(json.dumps({"key": "value", "key2": "va

ngnix解決訪問

  說到nginx,不得不說真的很強大,也帶來很多便利用於解決一些頭疼的難題。   一般來說可以用來做:靜態頁面的伺服器、靜態檔案快取伺服器、網站反向代理、負載均衡伺服器等等,而且實現這一切,基本只需要改改那萬能的配置檔案即可。 之前的博文記錄了作為負載均衡。這裡先記錄一下作為靜態頁面的伺服器和反向代理跨域

解決jquery ajax在訪問post請求的時候,ie9以下無效(包括ie9)的問題

jquery src actor div tick 屬性 dex 啟用 logs 最近在做項目的時候遇到一個問題,就是跨域請求ajax的時候ie9以下的瀏覽器不可以訪問,直接執行error裏面的代碼,但是也不報錯,就上網查了查,發現了一個很好用的方法,在這裏記錄一下,也希望

通過設置Ionic-Cli代理解決ionic serve調試問題

dbf this asc upa tails 訪問 web string 設置 Ionic-Cli代理設置: 打開ionic.config.json文件,添加proxies代理配置字段: { "name": "ion", "app_id": "", "v2":

[轉]No 'Access-Control-Allow-Origin' header is present on the requested resource.'Ajax訪問解決方案

不能 ade 方式 ole 相同域名 all log head 允許 原 https://blog.csdn.net/zhoucheng05_13/article/details/53580683 No ‘Access-Control-Allow-Origin‘ heade

分享訪問解決方案與基礎分析

什麼是跨域訪問? 由於瀏覽器同源策略,凡是傳送請求url的協議、域名、埠三者之間任意一個與當前頁面地址不同即為跨域。存在跨域的情況: 網路協議不同,如http協議訪問https協議。 埠不同,如80埠訪問8080埠。 域名不同,如qianduanblog.com訪問baidu.com。

ajax訪問問題解決

本文為轉載的一篇ajax跨域訪問問題解決方案 知跨域而不知如何解決 知道問題的確切原因,剩下的就是找到解決問題的方法了。google了好久,再次在同事的指點下知道jQuery的ajax有jsonp這樣的屬性可以用來解決跨域的問題。 找到一種解決方式 現在也知

iframe 訪問session/cookie丟失問題解決方法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

CORS解決ajax訪問問題---

/**  * 登入驗證  *   * @author ruoyi  */ @CrossOrigin(origins = "http://127.0.0.1:8020", maxAge = 36000) @Controller public

Shiro框架在CORS訪問中遇到的問題及解決

背景 最近做一個前後端分離的專案時,使用shiro做許可權管理時遇到跨域問題,這裡做一下記錄。   原因 後端通過Shiro配置URL過濾, shiroFilterFactoryBean.setLoginUrl("/unauth"); 預設對於沒有授權的訪問

【docker】elasticsearch-head無法連線elasticsearch的原因和解決,叢集健康值:未連線,ElasticSearch——訪問的問題

 環境 ==================== 虛擬機器啟動 centos 7  ip:192.168.92.130 elasticsearch 5.6.9   port:9200  9201 elasticSearch-head 5  p

Ajax訪問出現Uncaught SyntaxError: Unexpected token : 解決方案

在訪問外網提供的Api時出現跨域問題,嘗試使用普通方式JSONP解決,但是出現Uncaught SyntaxError: Unexpected token : 的錯誤,所有專注於研究ajax請求跨域問題,在前人基礎上逐漸理出脈絡,以此記之,希望對大家有所幫助。蒐羅資源比較雜亂,所有看到“

No 'Access-Control-Allow-Origin' header is present on the requested resource.'Ajax訪問解決方案

出現該錯誤是由於存在網站跨域訪問的問題。 什麼是網站跨域,簡單來講,當你通過ajax來請求或傳送資料時,兩個域名之間不能跨過域名來發送請求或者請求資料,瀏覽器會認為它是不安全的。 解決方式: 1、伺服器端解決方案 設定響應報文頭 response.setHeader

利用nginx解決vue的訪問問題

        vue在開發中,可以通過自帶的腳手架配置實現跨域訪問,但是打包時不會將這部分配置檔案載入,這樣會導致上了生產環境出現跨域訪問的問題。在網上查過一些解決跨域的問題,都沒太搞明白,然後就想採用nginx將服務請求轉發來實現,經過一天的摸索,終於搞定了。    

解決ajax訪問sessionid不一致問題

根據瀏覽器的保護規則,跨域的時候我們建立的sessionId是不會被瀏覽器儲存下來的,這樣,當我們在進行跨域訪問的時候,我們的sessionId就不會被儲存下來,也就是說,每一次的請求,伺服器就會以為是一個新的人,而不是同一個人,為了解決這樣的辦法,下面這種方法可以解決這種跨域的辦法。  

ajax訪問解決

ajax訪問域名遇見的跨域問題,在被訪問的nginx配置檔案上的http節點加上下面幾句話就好了。 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-