Встраивание весенне-загрузочного приложения Vaadin в HTML
Я уже разместил этот вопрос на форуме Vaadin, к сожалению, я не получил никакого ответа - возможно, ответ на вопрос лежит где-то между Spring-boot и Vaadin.
В настоящее время мне трудно встроить приложение Vaadin в HTML-страницу.
Что я использую:
Vaadin 7.6.6
vaadin-spring
spring-boot 1.3.5.RELEASE
Чтобы включить CORS в сочетании со Spring-Boot, я адаптировал запись в блоге Сами и создал следующий пользовательский сервлет CORS:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import com.vaadin.spring.server.SpringVaadinServlet;
/**
* This custom {@link SpringVaadinServlet} enables CORS in combination with
* Spring.
*
* @author Christoph Guse
*
*/
public class CORSServlet extends SpringVaadinServlet {
/**
*
*/
private static final long serialVersionUID = -2482991123719720492L;
/**
* Override to handle the CORS requests.
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Origin is needed for all CORS requests
String origin = request.getHeader("Origin");
if (origin != null && isAllowedRequestOrigin(origin)) {
// Handle a preflight "option" requests
if ("options".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
// allow the requested method
String method = request.getHeader("Access-Control-Request-Method");
response.addHeader("Access-Control-Allow-Methods", method);
// allow the requested headers
String headers = request.getHeader("Access-Control-Request-Headers");
response.addHeader("Access-Control-Allow-Headers", headers);
response.addHeader("Access-Control-Allow-Credentials", "true");
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().flush();
return;
} // Handle UIDL post requests
else if ("post".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Origin", origin);
response.addHeader("Access-Control-Allow-Credentials", "true");
super.service(request, response);
return;
}
}
// All the other requests nothing to do with CORS
super.service(request, response);
}
/**
* Check that the page Origin header is allowed.
*/
private boolean isAllowedRequestOrigin(String origin) {
// TODO: Remember to limit the origins.
return origin.matches(".*");
}
}
Кроме того, я нашел некоторую документацию о Spring-Boot и CORS, поэтому я добавил эту конфигурацию Spring:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import CORSServlet;
/**
* @author Christoph Guse
*
*/
@Configuration
public class AuthAppVaadinApplicationConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins(".*");
}
};
}
@Bean(name="vaadinServlet")
public CORSServlet corsServlet(){
return new CORSServlet();
}
}
Мой HTML выглядит так:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=9;chrome=1" />
<title>Embedding a Vaadin Application in HTML Page</title>
<!-- Set up the favicon from the Vaadin theme -->
<link rel="shortcut icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/reindeer/favicon.ico" />
<link rel="icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/reindeer/favicon.ico" />
</head>
<body>
<!-- Loads the Vaadin widget set, etc. -->
<script type="text/javascript"
src="http://vaadin.poc:8090/VAADIN/vaadinBootstrap.js?v=7.6.6"></script>
<h1>Embedding a Vaadin UI</h1>
<p>This is a static web page that contains an embedded Vaadin
application. It's here:</p>
<!-- So here comes the div element in which the Vaadin -->
<!-- application is embedded. -->
<div style="width: 100%; height: 75vh; border: 2px solid green;"
id="helloworld" class="v-app">
<!-- Optional placeholder for the loading indicator -->
<div class=" v-app-loading"></div>
<!-- Alternative fallback text -->
<noscript>You have to enable javascript in your browser to
use an application built with Vaadin.</noscript>
</div>
<script type="text/javascript">//<![CDATA[
if (!window.vaadin)
alert("Failed to load the bootstrap JavaScript: "+
"VAADIN/vaadinBootstrap.js");
/* The UI Configuration */
vaadin.initApplication("helloworld", {
"browserDetailsUrl": "http://vaadin.poc:8090/",
"serviceUrl": "http://vaadin.poc:8090/",
"theme": "valo",
"versionInfo": {"vaadinVersion": "7.6.6"},
"widgetset": "com.vaadin.DefaultWidgetSet",
"vaadinDir": "http://vaadin.poc:8090/VAADIN/",
"heartbeatInterval": 300,
"debug": true,
"standalone": false,
"authErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Authentication problem"
},
"comErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Communication problem"
},
"sessExpMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Session Expired"
}
});//]] >
</script>
<p>Please view the page source to see how embedding works.</p>
</body>
</html>
Моя проблема в том, что приложение изначально загружено, но несколько значков отсутствуют, и если я запускаю действие в приложении, то есть открываю выпадающий список, то приложение не может установить соединение с приложением весенней загрузки. Сообщения об ошибках выглядят так:
XMLHttpRequest cannot load http://vaadin.poc:8090/UIDL/?v-uiId=0. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
Есть ли кто-нибудь, кому удалось встроить приложение весенней загрузки Vaadin в другое HTML-приложение?
Любая подсказка высоко ценится! Christoph
1 ответ
К счастью, кто-то на форуме Vaadin дал мне недостающую ссылку. Я забыл добавить немного JavaScript в автономный HTML:
<script>
XMLHttpRequest.prototype._originalSend = XMLHttpRequest.prototype.send;
var sendWithCredentials = function(data) {
this.withCredentials = true;
this._originalSend(data);
};
XMLHttpRequest.prototype.send = sendWithCredentials;
</script>
Это помогло, но шрифты не были должным образом загружены из-за проблем с CORS, поэтому я удалил пользовательский Vaadin CORSServlet и добавил поддержку CORS на основе фильтров, предоставляемую spring-boot (как описано в этой статье блога).
Мой пример теперь работает правильно, демонстрационное приложение полностью работоспособно, шрифты загружаются и используются правильно.
Пожалуйста, посмотрите https://github.com/flexguse/vaadin-html-embedding чтобы получить полностью рабочий пример.
Ура, Кристоф