I want to use of http://5.160.2.148:8091/api/trainTicketing/city/findAll rest for get cities in my angular project.
I used version 7.2.15 of angular in my project.
when get this url with httpClient throw following error :
Access to XMLHttpRequest at 'http://5.160.2.148:8091/api/trainTicketing/city/findAll' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
While at work correctly when enter url in browser and postman.
why ?
This question is related to
angular
Startup.cs in WebAPI.
app.UseCors(options => options.AllowAnyOrigin());
In ConfigureServices method:
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
In Controller:
[HttpGet]
[Route("GetAllAuthor")]
[EnableCors("AllowOrigin")]
Follow these steps
npm install --save cors
var cors = require('cors');
app.use(cors());
In my case using Angular and Spring Boot I solved that issue in my SecurityConfig:
http.csrf().disable().cors().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/register")
.anonymous()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
Or replace that line to:
http.csrf().disable().cors().and()
And other test option is to delete dependency from pom.xml and other code depend on it. It's like turn off security from Spring:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
You are all good at Angular side even postman not raise the cors policy issue. This type of issue is solved at back-end side in major cases.
If you are using Spring boot the you can avoid this issue by placing this annotation at your controller class or at any particular method.
@CrossOrigin(origins = "http://localhost:4200")
In case of global configuration with spring boot configure following two class:
`
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.csrf().disable()
.authorizeRequests()
.antMatchers("/api1/**").permitAll()
.antMatchers("/api2/**").permitAll()
.antMatchers("/api3/**").permitAll()
}
`
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("*")
.maxAge(3600L)
.allowedHeaders("*")
.exposedHeaders("Authorization")
.allowCredentials(true);
}
I Tried adding the below statement on my API on the express server and it worked with Angular8.
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET , PUT , POST , DELETE");
res.header("Access-Control-Allow-Headers", "Content-Type, x-requested-with");
next(); // Important
})
For nodejs
use the below code
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
For temporary testing during development we can disable it by opening chrome with disabled web security like this.
Open command line terminal and go to folder where chrome is installed i.e. C:\Program Files (x86)\Google\Chrome\Application
Enter this command:
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
A new browser window will open with disabled web security. Use it only for testing your app.
1: Create a class WebMvcConfig and extend it as shown from the WebMvcConfiguration and override addCorsMappings method.
2: Most importantly don't forget to make it @Configuration annotation because it should be loaded with Main Spring class to allow Cross-Origin.
@Configuration
public class WebMvcCofig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}
}
If you are using spring-boot for server side coding then please add a servlet filter and add the following code of your spring-boot application. It should work. Adding "Access-Control-Allow-Headers", "*"
is mandatory. Creation of proxy.conf.json is not needed.
@Component
@Order(1)
public class MyProjectFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,PUT,OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Max-Age", "86400");
chain.doFilter(req, res);
}
}
if You use spring boot , you should add origin link in the @CrossOrigin annotation
@CrossOrigin(origins = "http://localhost:4200")
@GetMapping("/yourPath")
You can find detailed instruction in the https://spring.io/guides/gs/rest-service-cors/
I was using https redirection just before adding cors middleware and able to fix the issue by changing order of them
What i mean is:
change this:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseHttpsRedirection();
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
...
}
to this:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseHttpsRedirection();
...
}
By the way, allowing requests from any origins and methods may not be a good idea for production stage, you should write your own cors policies at production.
The solution needs to add these headers to the server response.
'Access-Control-Allow-Origin', '*'
'Access-Control-Allow-Methods', 'GET,POST,OPTIONS,DELETE,PUT'
If you have access to the server, you can add them and this will solve your problem
OR
You can try concatentaing this in front of the url:
https://cors-anywhere.herokuapp.com/
If your project is .net Core 3.1 API project.
update your Startup.cs in your .net core project to:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:53135",
"http://localhost:4200"
)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddDbContext<CIVDataContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("CIVDatabaseConnection")));
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(MyAllowSpecificOrigins);
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Source: Stackoverflow.com