angular - navigationend - ¿Cómo crear una solicitud de dominio cruzado?
router events subscribe angular 4 (7)
¿Cómo crear una solicitud de dominio cruzado usando Angular 2?
¿Puede dar un ejemplo?
Como una solicitud entre localhost: 3000 y localhost: 8000 entre dominios
De hecho, no hay nada que hacer en Angular2 con respecto a las solicitudes de dominio cruzado. CORS es algo nativamente soportado por los navegadores. Este enlace podría ayudarlo a comprender cómo funciona:
- http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
- http://restlet.com/blog/2016/09/27/how-to-fix-cors-problems/
Para ser breves, en el caso de una solicitud de dominio cruzado, el navegador agrega automáticamente un encabezado
Origin
en la solicitud.
Hay dos casos:
-
Peticiones simples
Este caso de uso se aplica si utilizamos los métodos HTTP GET, HEAD y POST.
En el caso de los métodos POST, solo se admiten tipos de contenido con los siguientes valores:
text/plain
,application/x-www-form-urlencoded
ymultipart/form-data
. - Solicitudes verificadas previamente . Cuando no se aplica el caso de uso de "solicitudes simples", se realiza una primera solicitud (con el método OPCIONES HTTP) para verificar qué se puede hacer en el contexto de las solicitudes de dominio cruzado.
De hecho, la mayor parte del trabajo debe realizarse en el lado del servidor para devolver los encabezados CORS.
El principal es el de
Access-Control-Allow-Origin
.
200 OK HTTP/1.1
(...)
Access-Control-Allow-Origin: *
Para depurar estos problemas, puede usar herramientas de desarrollador dentro de los navegadores (pestaña Red).
Con respecto a Angular2, simplemente use el objeto
Http
como cualquier otra solicitud (el mismo dominio, por ejemplo):
return this.http.get(''https://angular2.apispark.net/v1/companies/'')
.map(res => res.json()).subscribe(
...
);
En mi experiencia, los complementos funcionaron con http pero no con el último httpClient. Además, la configuración de los encabezados de respuesta CORS en el servidor no era realmente una opción. Entonces, creé un archivo proxy.conf.json para actuar como un servidor proxy.
Lea más sobre esto aquí: https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md
a continuación está mi archivo prox.conf.json
{
"/posts": {
"target": "https://example.com",
"secure": true,
"pathRewrite": {
"^/posts": ""
},
"changeOrigin": true
}
}
Coloqué el archivo proxy.conf.json justo al lado del archivo package.json en el mismo directorio
luego modifiqué el comando de inicio en el archivo package.json como a continuación
"start": "ng serve --proxy-config proxy.conf.json"
ahora, la llamada http del componente de mi aplicación es la siguiente
return this._http.get(''/posts/pictures?method=GetPictures'')
.subscribe((returnedStuff) => {
console.log(returnedStuff);
});
Por último, para ejecutar mi aplicación, tendría que usar npm start o ng serve --proxy-config proxy.conf.json
Muchas respuestas largas (y correctas) aquí. Pero generalmente no hará estas cosas manualmente, al menos no cuando configure sus primeros proyectos para el desarrollo (aquí es donde generalmente se topa con estas cosas). Si usa koa para el backend: use koa-cors. Instalar a través de npm ...
npm install --save koa-cors
... y úsalo en el código:
const cors = require(''koa-cors'');
const Koa = require(''koa'');
const app = new Koa();
app.use(cors());
problema resuelto.
No es nada que pueda hacer en el lado del cliente.
@CrossOrigin
en el controlador en el lado del servidor y funciona.
@RestController
@CrossOrigin(origins = "*")
public class MyController
Por favor, consulte los docs .
Lin
Para mí fue otro problema. Esto puede ser trivial para algunos, pero me tomó un tiempo darme cuenta. Entonces esta respuesta podría ser útil para algunos.
Tenía mi
API_BASE_URL
establecida en
localhost:58577
.
La moneda cayó después de leer el mensaje de error por enésima vez.
El problema está en la parte donde dice que solo es compatible con
HTTP
y algunos otros protocolos.
Tuve que cambiar
API_BASE_URL
para que incluya el protocolo.
Así que cambiar
API_BASE_URL
a
http://localhost:58577
funcionó perfectamente.
Una de las formas de habilitar la solicitud de dominio cruzado en el navegador Chrome local:
- Crea un atajo de google chrome.
- Propiedades -> agregue "--disable-web-security --user-data-dir" al final del destino.
- Cierre o elimine todos los procesos de Google Chrome.
- Reinicie y presione la url de la interfaz de usuario.
Ahora la interfaz de usuario y la API que se ejecutan en diferentes puertos podrán trabajar juntas. Espero que esto ayude.
Si está buscando un ejemplo de solicitud de dominio cruzado. Lo pondré en fragmentos para que tengas suficiente idea.
- Cliente angular: http://localhost:4200/login
- Spring web-api para validar un usuario: http://localhost:8091/SpringWebService/login ''
Cliente angular
user.service.ts para llamar al SpringWebservice .
/** POST: Validates a user for login from Spring webservice */
loginUrl = ''http://localhost:8091/SpringWebService/login''; // URL to web api
validUser (user: User): Observable<User> {
return this.http.post<User>(this.loginUrl, user, httpOptions)
.pipe(
catchError(this.handleError(''Login User'', user))
);
}
const httpOptions = {
headers: new HttpHeaders({
''Content-Type'': ''application/json;charset=utf-8'',
''Authorization'': ''my-auth-token''
})
};
login.component.html : para aceptar el nombre de usuario y pwd.
<form (ngSubmit)="onSubmit(loginForm)" #loginForm="ngForm">
<!-- //ngModel is a must for each form-control -->
<!-- 1st group -->
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required name="name" ngModel #name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
Name is required
</div>
</div>
<!-- 2nd group -->
<div class="form-group">
<label for="pwd">Password</label>
<input type="text" class="form-control" id="pwd"
name="pwd" #pwd required ngModel>
</div>
<button type="submit" class="btn btn-success" [disabled]="!loginForm.valid">Submit</button>
</form>
login.component.ts : llama y suscribe el método validUser de user.service.
userModel : User;
onSubmit(loginForm : NgForm) {
this.submitted = true;
console.log("User : "+loginForm.value.name + " Valid :"+loginForm.valid)
this.userModel.loggedIn= false;
this.userModel=new
User(loginForm.value.name.trim(),loginForm.value.pwd.trim())
// Passing the userModel to Service method to invoke WebAPI
this.userService.validUser(this.userModel).subscribe(user=>
{
if(user.loggedIn == false){
console.log("Invalid User/PWD");
}
else{
this.userService.changeUser(this.userModel);
this.router.navigate([''/home'']);
}
}
);
user.ts: modelo.
export class User {
constructor(
public name : String,
public pwd : String,
public email ?: String, //optional
public mobile ? : number,//""
public loggedIn : boolean = false
){ }
}
Servicio web de primavera .
package com.rest;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
// This annotation opens door for cross-domain(Cross-origin resource sharing (CORS)) from any host
@CrossOrigin(origins="*")
public class MainController {
@RequestMapping(value="/login", method=RequestMethod.POST)
public User validUser(@RequestBody User user){
BaseResponse response = new BaseResponse();
if(user.getName().equalsIgnoreCase("shaz") && user.getPwd().equals("pwd")){
user.setLoggedIn(true);
}
else{
user.setLoggedIn(false);
}
return user;
}
}
Ahora, cuando pasa el nombre como "shaz" y pwd como "pwd" en el formulario y presiona enviar, se valida desde SpringWebService y el indicador loginIn se establece en verdadero y la entidad de usuario se devuelve en respuesta. Según el estado de inicio de sesión de la respuesta, el usuario es redirigido a la página de inicio o se genera un error.
Página de inicio de sesión y detalles de la red
Nota: no he compartido la configuración y el código completos
Consulte esto: https://shahbaazdesk.wordpress.com/2018/04/03/angular5-with-spring-webservice/
@RestController
@RequestMapping(value = "/profile")
@CrossOrigin(origins="*")
public class UserProfileController {
SpringREST proporciona anotaciones @CrossOrigin donde (origins = "*") permite el acceso a REST APIS desde cualquier fuente.
Podemos agregarlo a la API respectiva o al RestController completo.