[英]Angular CORS request blocked
我正在尝试将我的 Angular 应用程序与 Express 上的简单 REST 服务器连接起来。 服务器仅发送json
数据以响应请求。 为了添加CORS
支持,我使用了 npm 中的cors
模块。 在 Angular 应用程序上,我按照以下问题的说明添加了HttpHeaders
: Angular 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.