Ste*_*pUp 11 c# asp.net-core angular-universal asp.net-core-webapi angular
我开发了一个使用ASP.NET Core Web API和构建的Web应用程序Angular 4.我的模块捆绑器是Web Pack 2.
我想通过Facebook,Twitter,Google使我的应用程序可抓取或链接共享.url当某些用户试图在Facebook上发布我的新闻时,必须是相同的.例如,Jon希望与http://myappl.com/#/hellopageFacebook 共享页面 - 在Facebook上,然后Jon将此链接插入Facebook : http://myappl.com/#/hellopage.
我已经看过这个没有标签帮助器的Angular Universal服务器端渲染教程,并希望进行服务器端渲染.因为我使用ASP.NET Core Web API,我的Angular 4应用程序没有任何.cshtml视图,所以我无法从控制器发送数据ViewData["SpaHtml"]从我的控制器查看:
ViewData["SpaHtml"] = prerenderResult.Html;
Run Code Online (Sandbox Code Playgroud)
另外,我看到了Angular Universal的这个谷歌教程,但他们使用的是NodeJS服务器,而不是ASP.NET Core.
我想使用服务器端预呈现.我通过这种方式添加元标记:
import { Meta } from '@angular/platform-browser';
constructor(
private metaService: Meta) {
}
let newText = "Foo data. This is test data!:)";
//metatags to publish this page at social nets
this.metaService.addTags([
// Open Graph data
{ property: 'og:title', content: newText },
{ property: 'og:description', content: newText }, {
{ property: "og:url", content: window.location.href },
{ property: 'og:image', content: "http://www.freeimageslive.co.uk/files
/images004/Italy_Venice_Canal_Grande.jpg" }]);
Run Code Online (Sandbox Code Playgroud)
当我在浏览器中检查此元素时,它看起来像这样:
<head>
<meta property="og:title" content="Foo data. This is test data!:)">
<meta property="og:description" content="Foo data. This is test data!:)">
<meta name="og:url" content="http://foourl.com">
<meta property="og:image" content="http://www.freeimageslive.co.uk/files
/images004/Italy_Venice_Canal_Grande.jpg"">
</head>
Run Code Online (Sandbox Code Playgroud)
我通常的方式引导应用程序:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Run Code Online (Sandbox Code Playgroud)
我的webpack.config.js配置看起来像这样:
var path = require('path');
var webpack = require('webpack');
var ProvidePlugin = require('webpack/lib/ProvidePlugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');
var isProd = (process.env.NODE_ENV === 'production');
function getPlugins() {
var plugins = [];
// Always expose NODE_ENV to webpack, you can now use `process.env.NODE_ENV`
// inside your code for any environment checks; UglifyJS will automatically
// drop any unreachable code.
plugins.push(new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}
}));
plugins.push(new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery'
}));
plugins.push(new CleanWebpackPlugin(
[
'./wwwroot/js',
'./wwwroot/fonts',
'./wwwroot/assets'
]
));
return plugins;
}
module.exports = {
devtool: 'source-map',
entry: {
app: './persons-app/main.ts' //
},
output: {
path: "./wwwroot/",
filename: 'js/[name]-[hash:8].bundle.js',
publicPath: "/"
},
resolve: {
extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html']
},
devServer: {
historyApiFallback: true,
stats: 'minimal',
outputPath: path.join(__dirname, 'wwwroot/')
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'tslint-loader',
enforce: 'pre'
},
{
test: /\.ts$/,
loaders: [
'awesome-typescript-loader',
'angular2-template-loader',
'angular-router-loader',
'source-map-loader'
]
},
{
test: /\.js/,
loader: 'babel',
exclude: /(node_modules|bower_components)/
},
{
test: /\.(png|jpg|gif|ico)$/,
exclude: /node_modules/,
loader: "file?name=img/[name].[ext]"
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['to-string-loader', 'style-loader', 'css-loader'],
},
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ["style", "css", "sass"]
},
{
test: /\.html$/,
loader: 'raw'
},
{
test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
loader: 'file?name=fonts/[name].[ext]'
}
],
exprContextCritical: false
},
plugins: getPlugins()
};
Run Code Online (Sandbox Code Playgroud)
是否可以在没有服务器端渲染的情况下进行ViewData?是否有另一种方法可以在ASP.NET Core Web API和Angular 2中进行服务器端渲染?
我已经将一个示例上传到github存储库.
Angular 中有一个选项可以使用 HTML5 样式的 url(不带哈希):LocationStrategy 和浏览器 URL 样式。您应该选择此 URL 样式。对于您想要在 Facebook 上共享的每个 URL,您需要呈现整个页面,如您引用的教程中所示。在服务器上拥有完整的 URL,您可以呈现相应的视图并返回 HTML。
@DávidMolnár 提供的代码可能非常适合此目的,但我还没有尝试过。
更新:
首先,为了使服务器预渲染工作,您不应该使用useHash: true它阻止向服务器发送路由信息。
在您引用的 GitHub 问题中提到的演示ASP.NET Core + Angular 2 通用应用程序中,ASP.NET Core MVC 控制器和视图仅用于以更方便的方式从 Angular 服务器预渲染 HTML。对于应用程序的其余部分,仅使用来自 .NET Core 世界的 WebAPI,其他一切都是 Angular 和相关的 Web 技术。
使用 Razor 视图很方便,但如果您严格反对它,您可以直接将 HTML 硬编码到控制器操作中:
[Produces("text/html")]
public async Task<string> Index()
{
var nodeServices = Request.HttpContext.RequestServices.GetRequiredService<INodeServices>();
var hostEnv = Request.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
var applicationBasePath = hostEnv.ContentRootPath;
var requestFeature = Request.HttpContext.Features.Get<IHttpRequestFeature>();
var unencodedPathAndQuery = requestFeature.RawTarget;
var unencodedAbsoluteUrl = $"{Request.Scheme}://{Request.Host}{unencodedPathAndQuery}";
TransferData transferData = new TransferData();
transferData.request = AbstractHttpContextRequestInfo(Request);
transferData.thisCameFromDotNET = "Hi Angular it's asp.net :)";
var prerenderResult = await Prerenderer.RenderToString(
"/",
nodeServices,
new JavaScriptModuleExport(applicationBasePath + "/Client/dist/main-server"),
unencodedAbsoluteUrl,
unencodedPathAndQuery,
transferData,
30000,
Request.PathBase.ToString()
);
string html = prerenderResult.Html; // our <app> from Angular
var title = prerenderResult.Globals["title"]; // set our <title> from Angular
var styles = prerenderResult.Globals["styles"]; // put styles in the correct place
var meta = prerenderResult.Globals["meta"]; // set our <meta> SEO tags
var links = prerenderResult.Globals["links"]; // set our <link rel="canonical"> etc SEO tags
return $@"<!DOCTYPE html>
<html>
<head>
<base href=""/"" />
<title>{title}</title>
<meta charset=""utf-8"" />
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"" />
{meta}
{links}
<link rel=""stylesheet"" href=""https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/0.8.2/css/flag-icon.min.css"" />
{styles}
</head>
<body>
{html}
<!-- remove if you're not going to use SignalR -->
<script src=""https://code.jquery.com/jquery-2.2.4.min.js""
integrity=""sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=""
crossorigin=""anonymous""></script>
<script src=""http://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.2.0.min.js""></script>
<script src=""/dist/main-browser.js""></script>
</body>
</html>";
}
Run Code Online (Sandbox Code Playgroud)
请注意,回退 URL 用于处理所有路由HomeController并渲染相应的 angular 路由:
builder.UseMvc(routes =>
{
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
Run Code Online (Sandbox Code Playgroud)
为了更容易开始,请考虑采用该演示项目并对其进行修改以适合您的应用程序。
更新 2:
如果您不需要使用来自 ASP.NET MVC 的任何东西,例如 Razor 和 NodeServices,那么在 Node.js 服务器上托管带有服务器预渲染的 Universal Angular 应用程序对我来说感觉更自然。并独立托管 ASP.NET Web Api,以便 Angular UI 可以访问不同服务器上的 API。我认为独立于 API 托管静态文件(并在情况下使用服务器预渲染)是一种非常常见的方法。
这是 Node.js 上托管的 Universal Angular 的初始存储库:https : //github.com/angular/universal-starter。
以下是如何在不同服务器上托管 UI 和 Web API 的示例:https : //github.com/thinktecture/nodejs-aspnetcore-webapi。注意 API URL 在urlService.ts.
此外,您可以考虑将 UI 和 API 服务器隐藏在反向代理之后,以便可以通过相同的公共域和主机访问两者,并且您不必处理 CORS 以使其在浏览器中工作。
| 归档时间: |
|
| 查看次数: |
3870 次 |
| 最近记录: |