我在 Lightsail 服务器上有一个 Angular 应用程序。它似乎运行正确
我在 4200 端口的网络选项卡中创建了规则
但我无法从外面到达它......
你能帮助我吗?
我使用 Angular8 作为前端,使用 Nodejs 作为后端
我已在生产中配置 WSS,但与客户端的连接无法正常工作,在一个页面连接正常但在另一页面连接不工作。
websocket 和服务器在同一个端口上运行
Ws(localhost) 一切正常
我们在后端使用的包
https://www.npmjs.com/package/ws
后端代码:
express = require('express');
app = express();
const http = require('http');
const port = 8080;
const fs = require('fs');
const certificate = {
cert: fs.readFileSync(''),
key: fs.readFileSync('')
}
const httpServer = http.createServer(app,certificate);
var server = require('ws');
var s = new server.Server({ server:httpServer },{
rejectUnauthorized: false
});
s.on('connection', function (ws) {
ws.on('message', function (message) {
var obj = JSON.parse(message);
if (obj.messagetype == "test") {
//send data
}
}
}
httpServer.listen(port);
前端代码
export class WebsocketService {
constructor() { }
private subject: Rx.Subject<MessageEvent>;
public connect(url): Rx.Subject<MessageEvent> {
if (!this.subject) {
this.subject = this.create(url);
}
return this.subject;
}
private create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);
let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
});
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
}
};
return Rx.Subject.create(observer, observable);
}
}
const CHAT_URL = "wss://cen.abcuae.com/";
export class SockoneService {
public messages: Subject<Message>;
public messages2: Subject<Message>;
constructor(wsService: WebsocketService) {
this.messages = <Subject<Message>>wsService.connect(CHAT_URL).pipe(map(
(response: MessageEvent): Message => {
let data = JSON.parse(response.data);
return data;
}));
this.messages2 = this.messages;
}
这是 /etc/nginx/sites-available/default 下的配置
server {
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/cen.abcuae.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cen.abcuae.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name cen.abcuae.com;
location / {
proxy_pass http://0.0.0.0:8080; #whatever port your app runs on
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 3600;
}
}
server {
listen 443;
listen [::]:443 ssl;
server_name cen.abcuae.com;
ssl_certificate /etc/letsencrypt/live/cen.abcuae.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cen.abcuae.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by C
location /websocket {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass https://cen.abcuae.com:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
对于需要托管在 IIS 服务器上的 Angular 应用程序,我必须将完整的 URL 从 HTTP 重定向到 HTTPS。
我创建了以下规则,但它不起作用,它只适用于主域(如http://www.somedomain.com,它重定向就好了,但使用http://www.somedomain.com/route
这是我的规则。我究竟做错了什么?
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="Angular Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="./index.html" />
</rule>
</rules>
这个想法是将http://www.somedomain.com/route/something或http://somedomain.com/route/something重定向到https://www.somedomain.com/route/something
网上有几个关于同一主题的问题,但没有任何效果。
我有一个运行 Angular 应用程序的 serverXYZ、一个用于身份验证的后端 tomcat webapp、一个 nginx 服务器。Angular 应用程序在 4200 端口,tomcat 应用程序在 8080 端口。一切都在同一个主机上。
角度应用程序有一个 environment.ts 文件(注释字符串是我的测试之一,请参阅下面的 nginx conf):
export const environment = {
production: false,
// apiUrl: 'http://serverXYZ:444/api'
apiUrl: 'http://localhost:8080/backend'
};
nginx 配置文件:
server {
listen 444;
server_name serverXYZ;
location / {
proxy_pass http://localhost:4200;
//websocket
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_request_headers on;
proxy_http_version 1.0;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 120s;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
location /api {
proxy_pass http://localhost:8080/backend;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
}
后端 tomcat 应用程序在其 web.xml 中有这个:
...
<!-- Tomcat built in CORS implementation -->
<!-- https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<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,Authorization</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- End of built in CORS implementation -->
...
我使用我的电脑,打开浏览器,如果我连接到 http://serverXYZ:444,则使用描述的 conf 显示应用程序,但我在身份验证时收到 CORS 错误(CORS 请求失败)。相反,如果我在 environment.ts 中使用带有注释字符串的配置,则浏览器身份验证不会说 CORS,只是 403。当然,身份验证 api 已经过测试并且可以正常工作。
我一头雾水,怎么了?此外,使用 nginx 解决这个问题是我的首选方式,但不是强制性的。
编辑: 我添加了更多信息,我正在使用 "ng serve --disableHostCheck=true" 启动 Angular 应用程序。我不知道在这种情况下是否应该使用“--publicHost”选项或“--host 0.0.0.0”?
编辑 2: 我刚才看到的另一件事,Firefox 在 OPTIONS 请求上没有给我任何错误,只是在 POST 上出现 Cors。