簡體   English   中英

Angular CORS 請求被阻止

[英]Angular CORS request blocked

我正在嘗試將我的 Angular 應用程序與 Express 上的簡單 REST 服務器連接起來。 服務器僅發送json數據以響應請求。 為了添加CORS支持,我使用了 npm 中的cors模塊。 在 Angular 應用程序上,我按照以下問題的說明添加了HttpHeadersAngular CORS request blocked

這是我在 express 中設置 cors 選項的代碼:`

// async CORS setup delegation
function corsOptsDelegator(req, cb) {
    let opts = {},
        origin = req.header('Origin');
    if(imports.allowedOrigins.indexOf(origin) === 1) opts.origin = true;
    else opts.origin = false;
    opts.optionsSuccessStatus = 200;
    opts.methods = ['POST', 'GET']; // allowed methods
    opts.credentials = true; // for passing/setting cookie 
    opts.allowedHeaders = ['Content-Type', 'Accept', 'Access-Control-Allow-Origin']; // restrict headers 
    opts.exposedHeaders = ['Accept', 'Content-Type']; // for exposing custom headers to clients; use for hash
    cb(null, opts);
}
`

以下是我將它添加到全局get處理程序的方法:

`
app.get('/', cors(corsOptsDelegator), (res, req, nxt) => {
    // only for adding cors on all requests
    nxt();
});
`

以下是我設置 Angular 服務的方式:

`

export class ContentGetterService {

  private root: string;
  private corsHeaders: HttpHeaders;
  //private contents: string;

  constructor(private http: HttpClient) {
    this.root = 'http://localhost:8888';
    this.corsHeaders = new HttpHeaders({
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Access-Control-Allow-Origin': 'http://localhost:4200'
    });
    //this.contents = '';
   }

  getContent(subs: Array<string>): Observable<IContent> {
    return (() => {
      return this.http.get<IContent>( (() => {
        let r = this.root;
        subs.forEach((s, i, a) => {
          if(i === a.length-1) {
            r += s;
          }
          else {
            if(s !== '/') {
              r += s;
            }
          }
        });
        return r;
      })(), {
        headers: this.corsHeaders
      });

    })();
  }
  }

瀏覽器警告: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8888/. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8888/. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

謝謝。

如果您使用的是 angular-cli,則可以使用代理:

proxy.conf.json

{
  "/api": {
    "target": "http://localhost:8888",
    "secure": false
  }
}

將所有帶有/api前綴的請求重定向到 localhost:8888 而沒有任何 cors 問題。

官方文檔: https : //angular.io/guide/build#proxying-to-a-backend-server

首先,客戶端的問題是由於 Firefox 選擇處理飛行前 CORS 的行為。 沒有使用GET方法,而是使用了OPTIONS方法。 從我的代碼中可以明顯看出,我沒有任何處理OPTIONS處理程序。 經過一番谷歌搜索,我在 github 上發現了這篇文章: Express CORS 中間件 使用它並對我的客戶端請求標頭進行以下修改,我能夠正確啟動並運行它。 這是代碼:

CORS 中間件:

function myCors(req, res, nxt) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Origin, Content-Type, Accept, Accept-Language, Origin, User-Agent');
    if(req.method === 'OPTIONS') {
        res.sendStatus(204);
    }
    else {
        nxt();
    }
}`

將其掛載到應用實例: app.use(myCors);

在 Angular 客戶端服務上:

this.corsHeaders = new HttpHeaders({
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Access-Control-Allow-Origin': 'http://localhost:8888/'
});
// ... adding it to the request
getContent(subs: Array<string>): Observable<IContent> {
return (() => {
  return this.http.get<IContent>( (() => {
    let r = this.root;
    subs.forEach((s, i, a) => {
      if(i === a.length-1) {
        r += s;
      }
      else {
        if(s !== '/') {
          r += s;
        }
      }
    });
    return r;
  })(), {
    headers: this.corsHeaders
  });

})();
}

感謝大家的時間和努力。

在開發環境(本地主機)中,您可以輕松完成,無需遵循任何這些困難步驟。如果您使用的是 firefox,我認為您可以簡單地下載https://addons.mozilla.org/firefox/addon/cors-everywhere/ chrome 也必須有一個擴展。下載后它會出現在 firefox 菜單欄,然后​​你可以點擊它來激活它,這就是你現在可以訪問所有 apis 的所有內容,因為它會自動發送所有請求的標頭。對於生產環境,你必須通過將 access-control-allow-origin 添加到 * (all) 從您的服務器配置它

使用此代碼並根據您的結構管理自己。

app.use(
    cors({ 
        origin: http://localhost:4200, 
        methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
        allowedHeaders: [
            'Content-Type', 
            'Authorization', 
            'Origin', 
            'x-access-token', 
            'XSRF-TOKEN'
        ], 
        preflightContinue: false 
    })
);

app.get('/', (res, req, nxt) => {
    // only for adding cors on all requests
    nxt();
});

在角邊

constructor(private http: HttpClient) {
  this.root = 'http://localhost:8888';  //remove
  this.corsHeaders = new HttpHeaders({
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Access-Control-Allow-Origin': '/' .  // edit 
  });
  //this.contents = '';
 }

並使用<base> index.html

如果您正在使用 Angular CLI、NPM、Spring Data JPA 和 Tomcat 9,我終於找到了在應用程序服務器 (Tomcat) 上運行的前端 webapp (Angular) 和后端 webapp (Spring Data JPA) 之間進行通信的解決方案。

在開發環境中:

如果您在默認端口 4200 上運行ng serve ,則 Spring DAO 存儲庫中的注釋@CrossOrigin("localhost:4200")就可以了。

@CrossOrigin("http://localhost:4200")
public interface ConfigRepository extends JpaRepository<Config, String> {
    
}

在生產環境中:

如果您的應用程序在生產服務器上運行,您必須修改web.xml並添加(例如)內置 CORS 過濾器以允許訪問其他資源作為源。

<!-- ==================== CORS Filter Definition ====================== -->

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Access-Control-Allow-Origin</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Tomcat 9 CORS 過濾器的模板不同之處在於將Access-Control-Allow-Origin添加到cors.allowed.header並設置實際來源,例如http://localhost:8080

因此,無需為 HTTP 請求指定顯式標頭。 感謝@Neutrino。

允許您從 angular JS 訪問的服務器端,在這種情況下,您需要允許http://localhost:8888/因為這是您的服務器端 URL,angular 在http://localhost:4200 請檢查Http。 然后它工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM